yarv-dev:799
From: Minero Aoki <aamine loveruby.net>
Date: Thu, 02 Feb 2006 20:06:09 +0900 (JST)
Subject: [yarv-dev:799] open> Marshal.dump(NoMethodError)
青木です。
以下のプログラムで SEGV します。
~/c/yarv/BUGS/test_marshal % cat test_marshal.rb
begin
no_such_method()
rescue => err
Marshal.dump(err)
end
~/c/yarv/BUGS/test_marshal % ../../ruby -v test_marshal.rb
ruby 1.9.0 (2005-11-18) [x86_64-linux]
YARVCore 0.3.3 (rev: 356) [opts: ]
DBG> : "test_marshal.rb:4:in `rescue in <main>'"
DBG> : "test_marshal.rb:1:in `<main>'"
-- stack frame ------------
0x2a95ee2010 (0000): 00000001
0x2a95ee2018 (0001): 00000004
0x2a95ee2020 (0002): 00000004
0x2a95ee2028 (0003): 2a95eafec8
0x2a95ee2030 (0004): 2a95eafe28
0x2a95ee2038 (0005): 0066b701
0x2a95ee2040 (0006): 2a95eb38c0
0x2a95ee2048 (0007): 2a95eafe28
0x2a95ee2050 (0008): 00000001 <- lfp <- dfp
-- control frame ----------
c:0005 p:-001 s:0009 b:0009 l:0008 d:0008 CFUNC i:dump s: -
c:0004 p:0033 s:0006 b:0006 l:-754 d:0005 BLOCK i:rescue in <main> s: -
c:0003 p:0008 s:0004 b:0004 l:-754 d:-754 TOP i:<main> s: -
c:0002 p:-001 s:0001 b:0001 l:0000 d:0000 FINISH i:- s: -
c:0001 p:-001 s:0000 b:-001 l:0000 d:0000 ------ i:- s: -
---------------------------
[BUG] Segmentation fault
ruby 1.9.0 (2005-11-18) [x86_64-linux]
zsh: 25861 abort (core dumped) ../../ruby -v test_marshal.rb
原因は vm.c:th_eval_body() の以下のところだと思います。
if(state == TAG_RAISE){
rb_ivar_set(err, idThrowState, state);
}
ここで例外オブジェクトのインスタンス変数 #__ThrowState に TAG_RAISE (0x6)
をセットしているため、Marshal.dump すると Qundef として扱われてしまい、
落ちます。
以下のパッチのように FIXNUM にしたら落ちなくなりました。
Index: insns.def
===================================================================
--- insns.def (revision 358)
+++ insns.def (working copy)
@@ -1590,7 +1590,9 @@
th->state = GET_THROWOBJ_STATE(err);
}
else{
- th->state = rb_ivar_get(err, idThrowState);
+ VALUE st;
+ st = rb_ivar_get(err, idThrowState);
+ th->state = FIX2INT(st);
}
return err;
}
Index: vm.c
===================================================================
--- vm.c (revision 358)
+++ vm.c (working copy)
@@ -1289,7 +1289,7 @@
err = th->errinfo;
if(state == TAG_RAISE){
- rb_ivar_set(err, idThrowState, state);
+ rb_ivar_set(err, idThrowState, INT2FIX(state));
}
exception_handler:
--
青木峰郎
--
ML: yarv-dev quickml.atdot.net
使い方: http://www.atdot.net/~ko1/quickml
-> 799 2006-02-02 20:06 [aamine loveruby.net ] open> Marshal.dump(NoMethodError) 801 2006-02-04 08:46 ┗[ko1 atdot.net ] fixed> Re: open> Marshal.dump(NoMethodError)