From: Hiro Yoshioka Date: 2008-11-21T16:02:12+09:00 Subject: [ruby-dev:37134] Re: [Bug:1.9] removing Exception#initialize dumps core よしおかです。 > 遠藤です。 こんにちは、 > 2008/10/31 14:02 Yukihiro Matsumoto : > > In message "Re: [ruby-dev:36993] [Bug:1.9] removing Exception#initialize dumps core" > > on Thu, 30 Oct 2008 02:35:10 +0900, "Yusuke ENDOH" writes: > > > > |以下で SEGV しますが、仕様でしょうか。 > > | > > |$ ./ruby -e 'class Exception; remove_method(:initialize); end; raise' > > |-e:1: warning: removing `initialize' may cause serious problem > > |セグメンテーション違反です > > > > なにが起きてるかというと > > > > * raiseで例外オブジェクトを作ろうとする > > * Exception#initializeが削除されているので > > BasicObject#initializeを呼ぶ > > * BasicObject#initializeは引数を取らないので引数の数があわ > > ずArgumentError が発生する(raiseする) > > * raiseで例外オブジェクトを作ろうとする > > * 以下繰り返し。無限再帰でスタックを使いきってSEGV > > > > です。BasicObject#initializeを任意個の引数を受け付ける(で、無 > > 視する)ようにすれば、この問題はなくなりますが、たとえば > > Exception#initializeを内部で例外を発生するものに置き換えたり > > すれば同じことが起きます。 > > > > このことから考えるとあんまり直す必要はなさそうに思います。む > > しろ、(コストのことを考えなければ)無限再帰チェックを厳しくす > > る方が有効かと。 > > この件に関しては「直す必要がない」という判断もいいと思います。 > でもそれなら文章化した方がいいと思います。 > > とりあえず redmine に WontFix というエントリを作っておきました。 > http://redmine.ruby-lang.org/wiki/ruby-19/WontFix rubyの実装をまったくわかっていない門外漢なのですが、 =================================================================== --- vm_method.c (revision 20086) +++ vm_method.c (working copy) @@ -314,7 +314,7 @@ if (OBJ_FROZEN(klass)) rb_error_frozen("class/module"); if (mid == object_id || mid == __send__ || mid == idInitialize) { - rb_warn("removing `%s' may cause serious problem", rb_id2name(mid)); + rb_bug("removing `%s' may cause serious problem", rb_id2name(mid)); } if (st_lookup(RCLASS_M_TBL(klass), mid, &data)) { body = (NODE *)data; として、この時点でいさぎよく、abortさせるという作戦でいくと、先日の パッチとあわせわざで $ ./ruby -e 'class Exception; remove_method(:initialize); end; raise' -e:1: [BUG] removing `initialize' may cause serious problem ruby 1.9.0 (2008-11-01 revision 20086) [i686-linux] -- control frame ---------- c:0005 p:---- s:0012 b:0012 l:000011 d:000011 CFUNC :remove_method c:0004 p:0013 s:0008 b:0008 l:000007 d:000007 CLASS -e:1 c:0003 p:0009 s:0006 b:0006 l:000005 d:000005 TOP -e:1 c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH :inherited c:0001 p:0000 s:0002 b:0002 l:000001 d:000001 TOP :17 --------------------------- DBG> : "-e:1:in `remove_method'" DBG> : "-e:1:in `'" DBG> : "-e:1:in `
'" -- backtrace of native function call (Use addr2line) -- 0x8122c24 0x814e3dc 0x814e44b 0x811cc08 0x811cd62 0x81109dd 0x81128b3 0x811532d 0x8119664 0x811984c 0x805ce9f 0x805e682 0x805bd90 0xb7d7a685 0x805bc91 ------------------------------------------------------- Aborted と落ちてくれます。 rb_warn() でどうにかリカバリを試みているようですが、あきらめちゃうというのは だめなんでしょうか? だめなんだろうなあ。 よ -- Hiro Yoshioka Miracle Linux Corporation http://blog.miraclelinux.com/yume/ http://d.hatena.ne.jp/hyoshiok/