0

I am currently working on a way to bind an Mruby interpreter to Crystal projects. However, my current code segfaults on Windows (while running perfectly on WSL Ubuntu) with the 64bit Visual Studio environment and I do not find a solution for the problem.

Everything compiles fine and the program itself works, but as soon as I execute a Ruby command, it crashes (for debug and release builds) with an access violation.

@[Link(ldflags: "#{__DIR__}/build/lib/libmruby.lib msvcrt.lib Ws2_32.lib")] # Link mruby and standard library

lib Mruby # Generate bindings
    type MrbState = Void

    fun mrb_open() : MrbState*
    fun mrb_close(mrb : MrbState*)
    fun mrb_load_string(mrb : MrbState*, s : LibC::Char*)
end

mrb = Mruby.mrb_open() # Load context, works fine
Mruby.mrb_load_string(mrb, "puts 123") # This crashes the program
Mruby.mrb_close(mrb) # Close context again, would also work fine without the line above

puts "Everything okay" # Does not show

To compile the Crystal code, I wrote a batch script:

set CRYSTAL_PATH=%CD%\third_party\crystal\src;%CD%\third_party
set PATH=%PATH%;%CD%\third_party\crystal
set LIB=%LIB%;%CD%\third_party\crystal

cd third_party/mruby
ruby minirake MRUBY_BUILD_DIR="../../build" MRUBY_CONFIG="../../mruby_build_config.rb"
cd ../..

crystal build test.cr -o test.exe

The source codes for Crystal and Mruby are in the third_party directory, under the folders crystal and mruby, respectively. Links to the repos are:

https://github.com/mruby/mruby and https://github.com/crystal-lang/crystal

The Crystal binaries are obtained from the Github CI scripts for Windows and were just copied into the Crystal directory.

The config file for Mruby is simply:

MRuby::Build.new do |conf|
  if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
    toolchain :visualcpp
  else
    toolchain :gcc
  end

  conf.gembox 'default'

  conf.build_dir = ENV["MRUBY_BUILD_DIR"] || raise("MRUBY_BUILD_DIR undefined!")
end

The same program written in C does work, so the problem seems to be connected to Crystal somehow:

#include <mruby.h>
#include <mruby/compile.h>

int main() {
    mrb_state* mrb = mrb_open();
    mrb_load_string(mrb, "puts 123");
    mrb_close(mrb);
    return 0;
}

The C program was compiled using the following line:

cl main.c /I third_party/mruby/include msvcrt.lib Ws2_32.lib build/lib/libmruby.lib

I tried to debug the program with Visual Studio, but the debugger does not seem to be compatible with the Crystal-generated code. Changing compiler flags and defines did not help either.

I really have no idea where the problem is and don't know how to fix this or how to find out what causes it.

4

0 回答 0