From: Yusuke ENDOH Date: 2007-08-13T11:22:18+09:00 Subject: [ruby-dev:31394] Re: simultaneous exceptions dump core 遠藤です。 ソースコードがどういう前提で書かれているのかよくわからないので 3 つほどお聞きしたいです。 - rb_longjmp が JUMP_TAG(TAG_FATAL) を引き起こす件は、 「rb_longjmp は再入してはいけない関数なのに、今回は再入が起きている」のか、 「rb_longjmp は再入してもいい関数だけど、再入をうまく扱えていない」のか、 どっちでしょうか。 - JUMP_TAG(TAG_FATAL) が FIX2INT(Qnil) を引き起こす件は、 「FATAL が起きていいのは決められたタイミングだけなのに 今回は FATAL が起きてはいけないタイミングで起きている」のか、 「FATAL はいつ起きてもいいけれど、FATAL をうまく扱えていない」のか、 どっちでしょうか。 - 今回の件はマルチスレッド化に関する影響でしょうか。 一言で言うと、どこのバグなんでしょうか。 rb_longjmp は再入不可 + マルチスレッド化の影響あり、だとしたら、 rb_longjmp を呼ぶ全箇所で再入しないことを検討する必要が あるのかなー、とか。 上記の前提が正しければですが、rb_longjmp 中のコンテキストスイッチを 禁止できるならそれが簡単そうな気はします。多分。 > (1) すでに対象スレッドに例外が投げられていた場合、ブロック > (2) すでに対象スレッドに例外が投げられていた場合、キューイング > (3) すでに対象スレッドに例外が投げられていた場合、例外 「投げられていた」というのは、いつからいつまでのことでしょうか。 投げられた瞬間から、rescue か ensure された瞬間まで? (4) すでに対象スレッドに例外が投げられていた場合、無視 (false でも返す?) という選択肢もありでしょうか。 raise で通信したいとか考えなければ適当でいい気もします。 > しかし、Ctrl+C の問題は解決しなさそうな気がする...。 確かに最初のコードも Ctrl+C するとしばしば落ちますし、 以下でもしばしば落ちます (落ちないときもありますが) 。 $ ./ruby -ve ' Thread.abort_on_exception = true loop do begin Thread.start(Thread.current) { raise } raise rescue ensure end end ' ruby 1.9.0 (2007-08-13 patchlevel 0) [i686-linux] -- control frame ---------- c:0001 p:---- s:0001 b:-001 l:000000 d:000000 ------ --------------------------- -- backtrace of native function call (Use addr2line) -- 0x80dac65 0x80f4103 0x80f41cb 0x80b2250 0xffffe420 0x80575f4 0x8057643 0x805771c 0x8059eb2 0x8059f7e 0x805d410 0x80dd8db 0x80ddb53 0x80ddc71 0xb7ef1240 0xb7e2e3de ------------------------------------------------------- [BUG] Segmentation fault ruby 1.9.0 (2007-08-13) [i686-linux] アボートしました (core dumped) -- Yusuke ENDOH