Segmentation fault at raise exception

I get segfault at any Ruby exception with C API:

(gdb) bt
#0 0x00007ffff58ebd78 in siglongjmp () from /lib/libc.so.6
#1 0x00007ffff719d3e7 in rb_longjmp (tag=6, mesg=6652280) at eval.c:442
#2 0x00007ffff719d422 in rb_exc_raise (mesg=6652280) at eval.c:453
#3 0x00007ffff719a380 in rb_raise (exc=6723760,
fmt=0x7ffff72dc28c “no such file to load – %s”) at error.c:1172

It’s caused because GET_THREAD()->tag equal to 0x0.

Hi,

Could you show us the code? The interpreter may not be initialized
properly.

          matz.

In message “Re: Segmentation fault at raise exception.”
on Sat, 24 Apr 2010 23:38:34 +0900, O01eg Oleg [email protected]
writes:

|I get segfault at any Ruby exception with C API:
|
|(gdb) bt
|#0 0x00007ffff58ebd78 in siglongjmp () from /lib/libc.so.6
|#1 0x00007ffff719d3e7 in rb_longjmp (tag=6, mesg=6652280) at eval.c:442
|#2 0x00007ffff719d422 in rb_exc_raise (mesg=6652280) at eval.c:453
|#3 0x00007ffff719a380 in rb_raise (exc=6723760,
| fmt=0x7ffff72dc28c “no such file to load – %s”) at error.c:1172
|
|It’s caused because GET_THREAD()->tag equal to 0x0.

Hi,

In message “Re: Segmentation fault at raise exception.”
on Sun, 25 Apr 2010 00:33:39 +0900, O01eg Oleg [email protected]
writes:

|It’s a initialization code:
|
| int ruby_argc = 1;
| char* ruby_argv[ruby_argc];
| ruby_argv[0] = “”;
| char** r_argv = ruby_argv;
| Logger::Instance().Log(L"Ruby starting");
| ruby_sysinit(&ruby_argc, &r_argv);
| Logger::Instance().Log(L"Ruby: Call RUBY_INIT_STACK");
| RUBY_INIT_STACK;
| Logger::Instance().Log(L"Ruby: Call ruby_init");
| ruby_init();
| Logger::Instance().Log(L"Ruby: Call ruby_init_loadpath");
| ruby_init_loadpath();
| Logger::Instance().Log(L"Ruby started");

Ah, I should have to say more clearly. Show us ALL of your code if
possible, to let us reproduce the problem.

          matz.

Here ALL my code: http://bin.mypage.sk/FILES/mud.tar.bz2

It’s a initialization code:

int ruby_argc = 1;
char* ruby_argv[ruby_argc];
ruby_argv[0] = “”;
char** r_argv = ruby_argv;
Logger::Instance().Log(L"Ruby starting");
ruby_sysinit(&ruby_argc, &r_argv);
Logger::Instance().Log(L"Ruby: Call RUBY_INIT_STACK");
RUBY_INIT_STACK;
Logger::Instance().Log(L"Ruby: Call ruby_init");
ruby_init();
Logger::Instance().Log(L"Ruby: Call ruby_init_loadpath");
ruby_init_loadpath();
Logger::Instance().Log(L"Ruby started");

Ok, now we have code. Next, how can we compile it?

Mere ‘automake --add-missing’ didn’t work. I saw

configure.ac:10: required file `configpkg.h.in’ not found

In addition, when I run

./configure --includedir=/usr/lib/ruby/1.8/i486-linux

I didn’t have AM_CHECK_RUBY, and configure failed to find <ruby.h>.

My version of automake was 1.11.1.

When we can compile it, then how can we run the program to reproduce
the problem?

          matz.

p.s.
I skim the code, you combined the interpreter with C++ code, C++
exceptions and threads, all of which are highly difficult to run
safely with the Ruby interpreter.

In message “Re: Segmentation fault at raise exception.”
on Sun, 25 Apr 2010 00:48:06 +0900, O01eg Oleg [email protected]
writes:

|Here ALL my code: http://bin.mypage.sk/FILES/mud.tar.bz2

Hi,

In message “Re: Segmentation fault at raise exception.”
on Sun, 25 Apr 2010 01:17:16 +0900, O01eg Oleg [email protected]
writes:

|I use autoreconf -fi
|AM_CHECK_RUBY places in m4/ruby.m4

OK, compile was done. You have to wrap any ruby code execution
between PUSH_TAG and POP_TAG, or you can use rb_protect() function
instead.

          matz.

I use autoreconf -fi
AM_CHECK_RUBY places in m4/ruby.m4

Thanks. Do I have to use this wrap for each thread which use ruby code?

In message “Re: Segmentation fault at raise exception.”
on Sun, 25 Apr 2010 02:10:04 +0900, O01eg Oleg [email protected]
writes:

|Thanks. Do I have to use this wrap for each thread which use ruby code?

You have to wrap every call for Ruby related (possibly exception
raising) functions, e.g. rb_require, rb_eval_string, etc. And bad
news is that if you call ruby functions from different threads, they
might crash, since some (or most) of them are not thread-safe.

          matz.

Yukihiro M. wrote:

You have to wrap every call for Ruby related (possibly exception
raising) functions, e.g. rb_require, rb_eval_string, etc.

Can I use

PUSH_TAG;
rb_requir(…)
rb_eval_string(…)
POP_TAG;

instead

PUSH_TAG;
rb_require(…)
POP_TAG;
PUSH_TAG;
rb_eval_string(…)
POP_TAG;

Hi,

In message “Re: Segmentation fault at raise exception.”
on Sun, 25 Apr 2010 02:23:22 +0900, O01eg Oleg [email protected]
writes:

|Can I use
|
| PUSH_TAG;
| rb_requir(…)
| rb_eval_string(…)
| POP_TAG;

Yes, but you have to do

PUSH_TAG();
if ((state = EXEC_TAG()) == 0) {
    rb_requir(...)
    rb_eval_string(...)
}
POP_TAG();

or use rb_protect utility function. My modified code was

static VALUE LoadFile0(VALUE filename)
{
return rb_require((const char *)filename);
}

void Ruby::RubyImpl::LoadFile(const char *filename)
{
int state;

rb_protect(LoadFile0, (VALUE)filename, &state);
// you can check state==0 for success.
}

          matz.

Thanks, it work.