I try embed ruby interpretator into my program. Program work well, but if ruby get exeption(in C or ruby itself), program crash with SEGFAULT. Expamle:
#include <iostream>
#include "Ruby/ruby.h"
#define RUBY_METH(method) reinterpret_cast< VALUE ( * ) ( ... ) >(method)
using namespace std;
int main(int argc, char** argv)
{
cout << "Hello world!" << endl;
ruby_sysinit(&argc, &argv);
RUBY_INIT_STACK;
ruby_init();
ruby_init_loadpath();
rb_require("./init");//segfault by "raise"
rb_raise(rb_eArgError, "Lol");//If comment "raise" in init.rb, segfault
return 0;
}
init.rb
p "lol"
raise
Console output
Hello world!
"lol"
<main>: [BUG] Segmentation fault
ruby 1.9.3p551 (2014-11-13) [i386-mingw32]
-- Control frame information -----------------------------------------------
c:0001 p:0000 s:0002 b:0002 l:000c74 d:000c74 TOP
-- C level backtrace information -------------------------------------------
C:\WINDOWS\SYSTEM32\ntdll.dll(ZwWaitForSingleObject+0xc) [0x76fbe5fc]
C:\WINDOWS\System32\KERNELBASE.dll(WaitForSingleObject+0x12) [0x75bdad52]
[0x004b2789]
[0x00402106]
[0x00402f6f]
[0x004f9e90]
[0x004011ea]
C:\WINDOWS\SYSTEM32\ntdll.dll(LdrSetAppCompatDllRedirectionCallback+0x1ae9d) [0x76fee0bd]
Compile with GNU GCC on windows
Late answer, but for anyone who might come across this, uncaught Ruby exceptions will segfault your application. When embedding Ruby in your application you need to use rb_protect
to catch the errors.
https://silverhammermba.github.io/emberb/c/#exceptions
If you’re compiling a library to be loaded by Ruby, you have it easy. Any exceptions raised in the API can be rescued as usual in your Ruby code. If you want to rescue an exception in the API, you can use rb_rescue2() which is similar to Ruby’s rescue.
...
If you’re embedding the Ruby interpreter in C, you need to be extremely careful when calling API functions that could raise exceptions: an uncaught exception will segfault the VM and kill your program. You could call rb_rescue2() with rb_eException, but there’s another approach for rescuing all exceptions:
rb_protect