catching segmentation faults from Ruby

I

Iain Dooley

hello, i've got ruby embedded into an application, and i've built a code
editor that allows you to edit ruby code for a GUI at runtime. only
problem is that something like this:

@parent.child("widgetName").display(@count)

will crash ruby if there is no child of parent with name "widgetName". i
know that there is rb_funcall_protect that allows you to trap errors,
but the problem is that i'm not doing an rb_funcall. the functions are
being called from with Qt/Ruby bindings. is there a way that i can trap
all errors from the ruby interpreter to prevent segfaults in dynamically
edited code from crashing the program?

cheers

iain
 
T

ts

I> will crash ruby if there is no child of parent with name "widgetName". i
I> know that there is rb_funcall_protect that allows you to trap errors,
I> but the problem is that i'm not doing an rb_funcall. the functions are
I> being called from with Qt/Ruby bindings. is there a way that i can trap
I> all errors from the ruby interpreter to prevent segfaults in dynamically
I> edited code from crashing the program?

Look at rb_eval_string_protect(), rb_protect()


Guy Decoux
 
T

ts

I> but surely i can't call:

I> rb_protect(app.exec(),VALUE ?,RESULT ?);

/* Something like this */

static VALUE
call_exec_for_app(QApplication *app)
{
return app->exec();
}

/* ... */
int status;
VALUE res;
/* ... */

res = rb_protect(call_exec_for_app, (VALUE)&app, &status);
if (status) {
/* there is a ruby error */
}
/* ... */



Guy Decoux
 
I

Iain Dooley

ts said:
I> but surely i can't call:

I> rb_protect(app.exec(),VALUE ?,RESULT ?);

/* Something like this */

static VALUE
call_exec_for_app(QApplication *app)
{
return app->exec();
}

/* ... */
int status;
VALUE res;
/* ... */

res = rb_protect(call_exec_for_app, (VALUE)&app, &status);
if (status) {
/* there is a ruby error */
}
/* ... */

excellent!! i thought that rb_protect was only for ruby methods.

i'll try that out. thanks very much

iain
 
I

Iain Dooley

ts said:
I> but surely i can't call:

I> rb_protect(app.exec(),VALUE ?,RESULT ?);

/* Something like this */

static VALUE
call_exec_for_app(QApplication *app)
{
return app->exec();
}

/* ... */
int status;
VALUE res;
/* ... */

res = rb_protect(call_exec_for_app, (VALUE)&app, &status);
if (status) {
/* there is a ruby error */
}
/* ... */

it appears that i can't pass the name of a C function to rb_protect.
i've tried these things:

/*** DEFINITION OF MY EXECUTE FUNCTION***/

VALUE executeApplication(void);

VALUE executeApplication()
{
return app->exec();
}

1) passing the C function to rb_protect as follows:

VALUE res = rb_protect(executeApplication, (VALUE)0, &status);

gives the following compile errors:

main.cpp:30: error: invalid conversion from `VALUE (*)()' to `VALUE
(*)(VALUE)'
main.cpp:30: error: initializing argument 1 of `VALUE rb_protect(VALUE
(*)(VALUE), VALUE, int*)'

2) using rb_define_method to define the method in ruby and then using
rb_const_get to get it out and then calling it:

rb_define_method(rb_cObject,"executeApplication",executeApplication,0);

VALUE res;
VALUE func = rb_const_get(rb_cObject,rb_intern("executeApplication"));
res = rb_protect(func, (VALUE)0, &status);

gives the following compile errors:

main.cpp:24: error: invalid conversion from `VALUE (*)()' to `VALUE
(*)(...)'
main.cpp:24: error: initializing argument 3 of `void
rb_define_method(VALUE, const char*, VALUE (*)(...), int)'
main.cpp:30: error: invalid conversion from `VALUE' to `VALUE (*)(VALUE)'
main.cpp:30: error: initializing argument 1 of `VALUE rb_protect(VALUE
(*)(VALUE), VALUE, int*)'

these types really confuse the hell out of me. what is VALUE(*)() ?!?!
VALUE everywhere... this is the last tiny little thing that i have to do
for the summer of code ends in two days ... just need to protect the
calls!

cheers

iain
 
T

ts

I> it appears that i can't pass the name of a C function to rb_protect.

use a typecast

Guy Decoux
 
I

Iain Dooley

ts said:
I> it appears that i can't pass the name of a C function to rb_protect.

use a typecast

okay, so i was able to use:

rb_protect((VALUE (*)(VALUE))executeApplication,(VALUE)0,&status);

thanks very much for your advice.

however, we are back to the original problem, because what is actually
happening is not a ruby exception, but is in fact a segmentation fault,
caused by a line such as this:

@parent.child("nonexistentChildWidget").text

because this code is being edited at runtime, if the user mistypes the
name of a child for example, then tests the code, i want an error to pop
saying "there was an error in your code" or something. at the moment, it
dies like this:

matt_test.rb:9: [BUG] Segmentation fault
ruby 1.8.2 (2004-12-25) [i386-freebsd5]

Abort (core dumped)

so i need a way to catch a segmentation fault, not ruby exceptions.

cheers

iain
 
T

ts

I> because this code is being edited at runtime, if the user mistypes the
I> name of a child for example, then tests the code, i want an error to pop
I> saying "there was an error in your code" or something. at the moment, it
I> dies like this:

I> matt_test.rb:9: [BUG] Segmentation fault
I> ruby 1.8.2 (2004-12-25) [i386-freebsd5]

Do it do the same thing when the script is called directly (outside the
embedded application) ?

If yes, it's a bug in this extension and it must be fixed.


Guy Decoux
 
I

Iain Dooley

ts said:
I> because this code is being edited at runtime, if the user mistypes the
I> name of a child for example, then tests the code, i want an error to pop
I> saying "there was an error in your code" or something. at the moment, it
I> dies like this:

I> matt_test.rb:9: [BUG] Segmentation fault
I> ruby 1.8.2 (2004-12-25) [i386-freebsd5]

Do it do the same thing when the script is called directly (outside the
embedded application) ?

If yes, it's a bug in this extension and it must be fixed.

well, actually the script doesn't do anything outside the application!!
it is just a class definition for receiving signals from a UI built in
Qt Designer.

this is part of Qt/Ruby bindings, so obviously what's happening is that,
because @parent.child("someName") returns nil, trying to access this is
causing a segmentation fault. so @parent.child("someName").text is
trying to call a function on an object that doesn't exist.

does that sound like it is a bug in Qt Ruby bindings?

cheers

iain
 
T

ts

I> this is part of Qt/Ruby bindings, so obviously what's happening is that,
I> because @parent.child("someName") returns nil, trying to access this is
I> causing a segmentation fault. so @parent.child("someName").text is
I> trying to call a function on an object that doesn't exist.

It must not segfault

moulon% ruby -e 'nil.text'
-e:1: undefined method `text' for nil:NilClass (NoMethodError)
moulon%

I> does that sound like it is a bug in Qt Ruby bindings?

try to reproduce it outside your embedded applications, if it segfault the
bug is in Qt ruby



Guy Decoux
 
I

Iain Dooley

ts said:
I> this is part of Qt/Ruby bindings, so obviously what's happening is that,
I> because @parent.child("someName") returns nil, trying to access this is
I> causing a segmentation fault. so @parent.child("someName").text is
I> trying to call a function on an object that doesn't exist.

It must not segfault

moulon% ruby -e 'nil.text'
-e:1: undefined method `text' for nil:NilClass (NoMethodError)
moulon%

I> does that sound like it is a bug in Qt Ruby bindings?

try to reproduce it outside your embedded applications, if it segfault the
bug is in Qt ruby

okay, thanks for your help.

iain
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top