From: Tomoyuki Chikanaga Date: 2009-01-19T20:51:24+09:00 Subject: [ruby-dev:37794] Re: [BUG]1.8.7-p72 で例外でもないのに大域脱出みたいな動作をする 度々すみません、近永と申します。 下記のパッチで問題の動作が直ったことと make test と make test-all の 結果を確認しました。 make test-all は 2 failures になりましたが、GDBMとOpenSSLだったので 本件とは無関係だろうと思います。 パッチはtar+bz2でダウンロードした1.8.7-p72に対するものです。 ご確認お願い致します。 --- node.h.orig 2009-01-19 20:37:00.000000000 +0900 +++ node.h 2009-01-19 20:35:58.000000000 +0900 @@ -479,7 +479,7 @@ #define rb_thread_raised_set(th, f) ((th)->flags |= (f)) #define rb_thread_raised_reset(th, f) ((th)->flags &= ~(f)) #define rb_thread_raised_p(th, f) (((th)->flags & (f)) != 0) -#define rb_thread_raised_clear(th) ((th)->flags = 0) +#define rb_thread_raised_clear(th) (rb_thread_raised_reset(th, RAISED_MASK)) #if defined(__cplusplus) } /* extern "C" { */ 以上。 Tomoyuki Chikanaga さんは書きました: > 日本コントロールシステムの近永と申します。 > > [ruby-dev:37776]で報告した件の続報ですが、 > patchlevel で二分探索して、patchlevel 48 から patchlevel 49 の > 間で動作が変化したことを確認しました。 > ChangeLog によると > Mon Jul 7 15:02:13 2008 Nobuyoshi Nakada > * eval.c (rb_longjmp): duplicate the thrown exception to set backtrace > if it was frozen. clear all raised flags. > > * eval.c (stack_check): leave clearing flag to rb_longjmp. > > * eval.c (rb_thread_set_raised, rb_thread_reset_raised): use generic > flags. > このへんが怪しような。 > 引き続き調査しますが、なにか見当はつきませんでしょうか。 > > 以上。 > > Tomoyuki Chikanaga wrote: >> 日本コントロールシステムの近永と申します。 >> >> 安定板 1.8.7-p72 で下記のスクリプトを実行すると想像と >> 違う動きをします。 >> うまく言えないのですが、例外が発生しているわけではないのに >> 例外で処理を抜けている時のように処理途中で抜けてしまいます。 >> 安定板リリースのパッチレベルを遡っていくと、 >> 1.8.7-p72, p71 では発生し、p22 では発生しませんでした。 >> とりあえず報告だけさせていただきます。 >> >> === 再現スクリプト ここから === >> require 'monitor' >> >> def meth1 >> mon = Monitor.new >> begin >> raise "dummy" # これがないと発生しない >> rescue >> end >> begin >> puts("=== before synchronize ===") >> mon.synchronize do >> nil >> end >> puts("### after synchronize... OK ###") >> rescue Exception >> puts("caught exception {$!:class}:#{$!}") >> end >> end >> >> def main >> Thread.exit >> ensure >> meth1 >> puts "#### after meth1 ####" >> Kernel.exit!(1) >> end >> >> thr = Thread.new{ main() } >> thr.join >> >> # main が直に Kernel.exit! するので >> # ここには来ないはず >> puts "should not reach here!!" >> === 再現スクリプト ここまで === >> >> * 実行結果 >> chikanaga@cluster05% ~/env/bin/ruby-1.8.7-p72 -v test.rb >> ruby 1.8.7 (2008-08-11 patchlevel 72) [i686-linux] >> === before synchronize === >> should not reach here!! >> >> % ~/env/bin/ruby-1.8.7-p71 -v test.rb >> ruby 1.8.7 (2008-08-08 patchlevel 71) [i686-linux] >> === before synchronize === >> should not reach here!! >> >> % ~/env/bin/ruby-1.8.7-p22 -v test.rb >> ruby 1.8.7 (2008-06-20 patchlevel 22) [i686-linux] >> === before synchronize === >> ### after synchronize... OK ### >> #### after meth1 #### >> >> * 実行環境 >> % uname -a >> Linux cluster05 2.4.21-47.ELsmp #1 SMP Wed Jul 5 20:38:41 EDT 2006 i686 >> i686 i386 GNU/Linux >> % cat /etc/issue >> Red Hat Enterprise Linux ES release 3 (Taroon Update 8) >> Kernel \r on an \m >> >> % gcc -v >> /usr/local/lib/gcc/i686-pc-linux-gnu/3.4.6/specs から spec を読み込み中 >> コンフィグオプション: ./configure --program-suffix=-3.4.6 >> --disable-shared --disable-ada --disable-java --disable-objc : >> (reconfigured) ./configure --program-suffix=-3.4.6 --disable-shared >> --enable-languages=c,c++,fortran : (reconfigured) ./configure >> --program-suffix=-3.4.6 --disable-shared >> --enable-languages=c,c++,fortran : (reconfigured) ./configure >> --program-suffix=-3.4.6 --disable-shared --enable-languages=c,c++,f77 >> スレッドモデル: posix >> gcc バージョン 3.4.6 >> >> 以上。 >> > -- Chikanaga Tomoyuki TEL: +81-45-477-5800 FAX: +81-45-477-5811 Nippon Control System Corp. 2-7-9 Shin-yokohama Kouhoku-ku Yokohama-shi Kanagawa-ken 222-0033 JAPAN