Re: [PATCH] fixed SIG_SEGV in check_stack() in eval.c
From:
b g <bg_rubyposter_123456@...>
Date:
2004-05-24 20:18:35 UTC
List:
ruby-core #2937
OK, here comes the C init and calling code. I end up doing about 23 million
Ruby calls after initialization (which is done only once). The idea here is
that we wish to provide a scripting language inside our app, without having
to build one ourselves. (We've maintained internal scripting languages in
the past, and it is wasteful of time given the existence of language such as
Ruby).
So we intend to load application variables into Ruby variables, call Ruby,
and transfer back results. Like I said, the number of Ruby calls will reach
into the several millions. Since our application depends upon being
extremely efficient (it's an EDA app that deals with very large data sets),
we need an efficient script-embedding API. This entire exercise is to
determine whether Ruby will be "fast enough."
Here's the calling code then. Keep in mind that the function
Ruby__simulated_compare__test() will be called many times. It does setup and
init stuff only once (including first rb_funcall()). Then it basically loads
data and calls rb_funcall() upon each subsequent invocation.
#include "ruby.h"
// These C-side vars get bound to Ruby vars:
static VALUE C_l_lay; static VALUE C_l_src; static VALUE C_l_err;
static VALUE C_w_lay; static VALUE C_w_src; static VALUE C_w_err;
static VALUE C_as_lay; static VALUE C_as_src; static VALUE C_as_err;
static VALUE C_ad_lay; static VALUE C_ad_src; static VALUE C_ad_err;
static VALUE C_ps_lay; static VALUE C_ps_src; static VALUE C_ps_err;
static VALUE C_pd_lay; static VALUE C_pd_src; static VALUE C_pd_err;
static bool bRubyIsInit=false; // init Ruby only once, call many times
static bool bTracePropertyError=false;
/* # The following script is implemented in one line in the psScript_rb string below:
# (had troubles getting rb_load_file() to work)
#
def bg_compare
loc_err=($l_lay-$l_src).abs/$l_src
if loc_err>0.0001 then; $l_err=loc_err; end
loc_err=($w_lay-$w_src).abs/$w_src
if loc_err>0.0001 then; $w_err=loc_err; end
loc_err=($as_lay-$as_src).abs/$as_src
if loc_err>0.0001 then; $as_err=loc_err; end
loc_err=($ad_lay-$ad_src).abs/$ad_src
if loc_err>0.0001 then; $ad_err=loc_err; end
loc_err=($ps_lay-$ps_src).abs/$ps_src
if loc_err>0.0001 then; $ps_err=loc_err; end
loc_err=($pd_lay-$pd_src).abs/$pd_src
if loc_err>0.0001 then; $pd_err=loc_err; end
end */
static char psScript_rb[] = "def bg_compare; \
loc_err=($l_lay-$l_src).abs/$l_src; \
if loc_err>0.0001 then; $l_err=loc_err; end; \
loc_err=($w_lay-$w_src).abs/$w_src; \
if loc_err>0.0001 then; $w_err=loc_err; end; \
loc_err=($as_lay-$as_src).abs/$as_src; \
if loc_err>0.0001 then; $as_err=loc_err; end; \
loc_err=($ad_lay-$ad_src).abs/$ad_src; \
if loc_err>0.0001 then; $ad_err=loc_err; end; \
loc_err=($ps_lay-$ps_src).abs/$ps_src; \
if loc_err>0.0001 then; $ps_err=loc_err; end; \
loc_err=($pd_lay-$pd_src).abs/$pd_src; \
if loc_err>0.0001 then; $pd_err=loc_err; end;\
end";
static ID bg_compare__ID; // lookup ID from name only once
inline void Ruby__simulated_compare__test()
{
if ( !bRubyIsInit ) {
// basic init stuff
ruby_init();
ruby_script("inside_application"); // simply sets $0 to simulated "self name"
C_l_lay=rb_float_new(0.0); rb_define_variable("$l_lay",&C_l_lay);
C_l_src=rb_float_new(0.0); rb_define_variable("$l_src",&C_l_src);
C_l_err=rb_float_new(0.0); rb_define_variable("$l_err",&C_l_err);
C_w_lay=rb_float_new(0.0); rb_define_variable("$w_lay",&C_w_lay);
C_w_src=rb_float_new(0.0); rb_define_variable("$w_src",&C_w_src);
C_w_err=rb_float_new(0.0); rb_define_variable("$w_err",&C_w_err);
C_as_lay=rb_float_new(0.0); rb_define_variable("$as_lay",&C_as_lay);
C_as_src=rb_float_new(0.0); rb_define_variable("$as_src",&C_as_src);
C_as_err=rb_float_new(0.0); rb_define_variable("$as_err",&C_as_err);
C_ad_lay=rb_float_new(0.0); rb_define_variable("$ad_lay",&C_ad_lay);
C_ad_src=rb_float_new(0.0); rb_define_variable("$ad_src",&C_ad_src);
C_ad_err=rb_float_new(0.0); rb_define_variable("$ad_err",&C_ad_err);
C_ps_lay=rb_float_new(0.0); rb_define_variable("$ps_lay",&C_ps_lay);
C_ps_src=rb_float_new(0.0); rb_define_variable("$ps_src",&C_ps_src);
C_ps_err=rb_float_new(0.0); rb_define_variable("$ps_err",&C_ps_err);
C_pd_lay=rb_float_new(0.0); rb_define_variable("$pd_lay",&C_pd_lay);
C_pd_src=rb_float_new(0.0); rb_define_variable("$pd_src",&C_pd_src);
C_pd_err=rb_float_new(0.0); rb_define_variable("$pd_err",&C_pd_err);
printf("About to give this script to Ruby: '%s'\n",psScript_rb); fflush(stdout);
rb_eval_string(psScript_rb); // hopefully this compiles to byte code...
rb_eval_string("x=Object.methods.sort; puts x"); // we should see 'bg_compare' listed
// Do the method name (to ID) lookup once. Use on subsequent // rb_funcall()s
bg_compare__ID = rb_intern ( "bg_compare" );
// Call once to test
VALUE dontcare = rb_funcall ( rb_cObject, bg_compare__ID, 0/*argc*/ /*, ... (none) */ );
rb_eval_string("puts $l_err"); // it gets init to 0.0 at creation, as expected
bRubyIsInit=true;
} else {
bTracePropertyError = false;
// Here's what we'll do each "real" time:
// -- load the variable values first:
RFLOAT(C_l_lay)->value = 69.69;
RFLOAT(C_l_src)->value = 69.70;
RFLOAT(C_l_err)->value = 0.0;
RFLOAT(C_w_lay)->value = 69.69;
RFLOAT(C_w_src)->value = 69.70;
RFLOAT(C_w_err)->value = 0.0;
RFLOAT(C_as_lay)->value = 69.69;
RFLOAT(C_as_src)->value = 69.70;
RFLOAT(C_as_err)->value = 0.0;
RFLOAT(C_ad_lay)->value = 69.69;
RFLOAT(C_ad_src)->value = 69.70;
RFLOAT(C_ad_err)->value = 0.0;
RFLOAT(C_ps_lay)->value = 69.69;
RFLOAT(C_ps_src)->value = 69.70;
RFLOAT(C_ps_err)->value = 0.0;
RFLOAT(C_pd_lay)->value = 69.69;
RFLOAT(C_pd_src)->value = 69.70;
RFLOAT(C_pd_err)->value = 0.0;
// -- Call Ruby function
VALUE dontcare = rb_funcall ( rb_cObject, bg_compare__ID, 0/*argc*/ /*, ... (none) */ );
// -- Deal with results
if ( RFLOAT(C_l_err)->value>0 ||
RFLOAT(C_w_err)->value>0 ||
RFLOAT(C_as_err)->value>0 ||
RFLOAT(C_ad_err)->value>0 ||
RFLOAT(C_ps_err)->value>0 ||
RFLOAT(C_pd_err)->value>0 ) {
bTracePropertyError = true;
}
}
} // Ruby__simulated_compare__test()
--- Yukihiro Matsumoto <matz@ruby-lang.org> wrote:
> Hi,
>
> In message "[PATCH] fixed SIG_SEGV in check_stack() in eval.c"
> on 04/05/22, b g <bg_rubyposter_123456@yahoo.com> writes:
>
> |I was getting a crash at 'JUMP_TAG(state);' in
> |check_stack() in eval.c because prot_tag was NULL.
> |The JUMP_TAG macro goes right after prot_tag without
> |checking it to be a valid pointer. *CRASH*
> |
> |Attached is my very simple fix. There's probly a
> |better way (I don't know why prot_tag is NULL in this
> |case, should it be?), but the patch below works for
> |me.
>
> It's probably caused by prot_tag left uninitialized by the
> application. Can you show us the portion of your application code
> that inistalize/call Ruby interpreter?
>
> matz.
__________________________________
Do you Yahoo!?
Friends. Fun. Try the all-new Yahoo! Messenger.
http://messenger.yahoo.com/