From: GOTOU Yuuzou Date: 2001-04-17T08:35:10+09:00 Subject: [ruby-dev:12977] Re: recursive malloc / fork deadlock / thread deadlock ごとうゆうぞうです。 In message <86oftyng8i.wl@archon.local.idaemons.org>, `"Akinori MUSHA" ' wrote: > At Mon, 16 Apr 2001 02:07:52 +0900, > GOTOU Yuuzou wrote: > おお。以前のパッチは忘れてよいのでしょうか。ぜひ取り込んでほしい > ですね。 あああ、すみません。freopen のが 抜けてました。やっぱ り [ruby-dev:12914] のほうがいいです。(fptr->f2 の分は 余計でしたが) 調子が悪くて集中力を欠いた状態で始めてしまって恥ずかし いミスを連発してしまいましたが、これで仕舞いにします。 何度も何度も本当にすみません。 > Solaris もこれで大丈夫なのでしょうか。 malloc が再入しているというメッセージは出ずに SIGSEGV/SIGBUS で死んでしまうのですが、発生しなくなっ たようです。 >  あとは fork したまま固まる問題ですね。 Ruby と直接関係ないのですが、これは FreeBSD の problem report に上がっている bin/25110 と同じみたいで す。 http://www.jp.FreeBSD.org/cgi/query-pr.cgi?pr=25110 まだ試していませんが、fork する前に一旦シグナルマスク をクリアとして、親でのみリストアするようにすればスレッ ド内で単に exec するケースについては解決するように思い ます。 しかし、子プロセス側でシグナルが使いものにならなくなる ようなので、今のところは --without-libc_r をデフォルト にするのが無難かもしれません。 # sigaltstack(2) を自前で呼べばなんとかなるとか。 $ cat fork_and_sig.rb pid = fork{ trap("TERM"){ puts "handler called!"; exit! } while true; end } sleep(1) Process.kill("TERM", pid) puts "waitpid start" Process.waitpid(pid) puts "waitpid end" $ LD_PRELOAD=/usr/lib/libc.so ruby fork_and_sig.rb waitpid start handler called! waitpid end # ちゃんと終る $ $ ruby fork_and_sig.rb waitpid start # 終らないのでCtrl-C ^Cfork_and_sig.rb:8:in `waitpid': Interrupt from fork_and_sig.rb:8 $ ps PID TT STAT TIME COMMAND 590 p0 DWs 0:01.62 -bash (bash) 16159 p0 MW 0:05.38 ruby fork_and_sig.rb 16160 p0 RW+ 0:00.00 ps 8022 p1 DWs+ 0:00.94 -bash (bash) $ kill -QUIT 16159 $ ps PID TT STAT TIME COMMAND 590 p0 DWs 0:01.63 -bash (bash) 16159 p0 MW 0:30.80 ruby fork_and_sig.rb 16162 p0 RW+ 0:00.00 ps 8022 p1 DWs+ 0:00.94 -bash (bash) $ kill -9 16159 -- ごとうゆうぞう --- io.c.orig Tue Apr 17 05:35:01 2001 +++ io.c Tue Apr 17 05:56:20 2001 @@ -1379,6 +1379,10 @@ rb_sys_fail(fname); } } +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(sun) + if (setvbuf(file, NULL, _IOFBF, 0) != 0) + rb_warn("setvbuf() can't be honered for %s.", fname); +#endif #ifdef __human68k__ fmode(file, _IOTEXT); #endif @@ -1402,6 +1406,10 @@ rb_sys_fail(0); } } +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(sun) + if (setvbuf(file, NULL, _IOFBF, 0) != 0) + rb_warn("setvbuf() can't be honered (fd=%d).", fd); +#endif return file; } @@ -1925,6 +1933,10 @@ if (freopen(RSTRING(fname)->ptr, mode, fptr->f) == 0) { rb_sys_fail(fptr->path); } +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(sun) + if (setvbuf(fptr->f, NULL, _IOFBF, 0) != 0) + rb_warn("setvbuf() can't be honered for %s.", RSTRING(fname)->ptr); +#endif if (fptr->f2) { if (freopen(RSTRING(fname)->ptr, "w", fptr->f2) == 0) { rb_sys_fail(fptr->path);