[#18440] racc segv revisited — "Akinori MUSHA" <knu@...>

 次のバグの件なんですが、現時点では原因究明を含めて未解決という

24 messages 2002/10/02
[#18617] Re: racc segv revisited — "Akinori MUSHA" <knu@...> 2002/11/02

At Wed, 2 Oct 2002 23:19:59 +0900,

[ruby-dev:18445] Re: [ruby-cvs] ruby/ext/tcltklib: * eval.c (ruby_run): should set toplevel visibility again here.

From: nobu.nakada@...
Date: 2002-10-03 08:31:22 UTC
List: ruby-dev #18445
なかだです。

At Thu, 3 Oct 2002 16:33:47 +0900,
Yukihiro Matsumoto wrote:
> |> むう、修正しておきます。
> |
> |rb_f_lambda()を使うようになってますが、これでできるんでしたっけ。
> |たしかPUSH_ITER(ITER_CUR)してなくてできないので、rb_proc_new()
> |が必要だったような気がするのですが。
> |
> |      *(q->result) = rb_funcall(rb_iterate(rb_f_lambda, 0, ivq_safelevel_handler, 
> |					   Data_Wrap_Struct(rb_cData,0,0,q)), 
> |				rb_intern("call"), 0);
> 
> あれえ、できなかったっけか。

ように思うんですが。そもそもこのivq_safelevel_handlerがどういう
ときに呼ばれるかよく分かってなくてテストしてないんですが、こう
いうサンプルではエラーになります。

$ cat lambda.c
#include <ruby.h>

static VALUE
callback(VALUE arg)
{
    rb_p(arg);
}

void
Init_lambda()
{
    VALUE l = rb_iterate((VALUE (*)_((VALUE)))rb_f_lambda, 0, callback, Qnil);
    rb_gvar_set("$lambda", l);
}

$ ruby-1.6 -v -rlambda -e0
ruby-1.6: tried to create Proc object without a block (ArgumentError)
ruby 1.6.8 (2002-10-02) [i686-linux]

うーん、拡張ライブラリで例外が起きたときのファイル名がおかしい…。


Index: eval.c
===================================================================
RCS file: /cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.338
diff -u -2 -p -r1.338 eval.c
--- eval.c	27 Sep 2002 09:42:24 -0000	1.338
+++ eval.c	3 Oct 2002 08:28:54 -0000
@@ -888,4 +888,6 @@ static VALUE trace_func = 0;
 static int tracing = 0;
 static void call_trace_func _((char*,NODE*,VALUE,ID,VALUE));
+#define ENABLE_TRACE() (tracing &= ~2)
+#define DISABLE_TRACE() (tracing |= 2)
 
 #define SET_CURRENT_SOURCE() (ruby_sourcefile = ruby_current_node->nd_file, \
@@ -1867,5 +1869,5 @@ is_defined(self, node, buf)
       check_bound:
 	{
-	    int call = nd_type(node)== NODE_CALL;
+	    int call = nd_type(node)==NODE_CALL;
 
 	    val = CLASS_OF(val);
@@ -4500,6 +4502,8 @@ rb_call0(klass, recv, id, oid, argc, arg
 	    if (trace_func) {
 		int state;
+		volatile int old_tracing = tracing;
 
 		call_trace_func("c-call", ruby_current_node, recv, id, klass);
+		DISABLE_TRACE();
 		PUSH_TAG(PROT_FUNC);
 		if ((state = EXEC_TAG()) == 0) {
@@ -4507,4 +4511,5 @@ rb_call0(klass, recv, id, oid, argc, arg
 		}
 		POP_TAG();
+		tracing = old_tracing;
 		ruby_current_node = ruby_frame->node;
 		call_trace_func("c-return", ruby_current_node, recv, id, klass);
@@ -4969,4 +4974,5 @@ eval(self, src, scope, file, line)
     NODE *nodesave = ruby_current_node;
     volatile int iter = ruby_frame->iter;
+    volatile int old_tracing = tracing;
     int state;
 
@@ -5031,4 +5037,5 @@ eval(self, src, scope, file, line)
 	}
 	if (!NIL_P(result)) ruby_errinfo = result;
+	ENABLE_TRACE();
 	result = eval_node(self, node); 
     }
@@ -5072,4 +5079,5 @@ eval(self, src, scope, file, line)
     ruby_current_node = nodesave;
     ruby_set_current_source();
+    tracing = old_tracing;
     if (state) {
 	if (state == TAG_RAISE) {
@@ -5305,4 +5313,5 @@ rb_load(fname, wrap)
     volatile VALUE wrapper = 0;
     volatile VALUE self = ruby_top_self;
+    volatile int old_tracing = tracing;
     NODE *saved_cref = ruby_cref;
     TMP_PROTECT;
@@ -5358,4 +5367,5 @@ rb_load(fname, wrap)
 	ALLOW_INTS;
 	if (ruby_nerrs == 0) {
+	    ENABLE_TRACE();
 	    eval_node(self, node);
 	}
@@ -5373,4 +5383,5 @@ rb_load(fname, wrap)
     POP_VARS();
     ruby_wrapper = wrapper;
+    tracing = old_tracing;
     if (ruby_nerrs > 0) {
 	ruby_nerrs = 0;
@@ -5577,5 +5588,11 @@ rb_f_require(obj, fname)
     {
 	int volatile old_vmode = scope_vmode;
+	NODE *const volatile old_node = ruby_current_node;
+	const volatile old_func = ruby_frame->last_func;
 
+	ruby_current_node = 0;
+	ruby_sourcefile = rb_source_filename(RSTRING(fname)->ptr);
+	ruby_sourceline = 0;
+	ruby_frame->last_func = 0;
 	PUSH_TAG(PROT_NONE);
 	if ((state = EXEC_TAG()) == 0) {
@@ -5587,4 +5604,7 @@ rb_f_require(obj, fname)
 	}
 	POP_TAG();
+	ruby_current_node = old_node;
+	ruby_set_current_source();
+	ruby_frame->last_func = old_func;
 	SCOPE_SET(old_vmode);
     }


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread