From: WATANABE Tetsuya Date: 1999-06-14T10:33:09+09:00 Subject: [ruby-dev:7109] Re: Ruby 1.3.4-990611 渡辺哲也です。 動きが変わったのでお知らせします。 ruby-1.3.4-990611 Linux 2.0.26 (glibc-2.0.7) $stdout = IO.popen('nkf -j', 'w') のように $stdout を上書きすると、出力時にプロセスがブロック してしまうことが起きました。 ターミナルから C-c (intr) すると SIGPIPE (SignalException) と表示されます。 簡単な再現スクリプトが書けず、とりあえずお知らせということ で。 ■ 回避策 io.c 1495 に rb_obj_call_init((VALUE)port, 0, 0); を追加。これは一つ前のリリースとの差から(他への影響はよくわ からないです)。 または w = IO.popen('nkf -j', 'w') $stdout = w と書く。 GC との関係がありそうで、スクリプトから不要? な部分を削ると 起きません。 それと IO.popen で nkf は使わずに NKF.nkf する。 ■ 止っているときの状況 gdb 上で再現して、止っているところを backtrace しました。 #0 0x400bc7f9 in __wait4 () #1 0x400f66cc in __DTOR_END__ () #2 0x807870c in rb_lastline_set () #3 0x8078b6f in rb_syswait () #4 0x8064289 in rb_io_ungetc () #5 0x80642ce in rb_io_ungetc () #6 0x80642f9 in rb_io_fptr_finalize () #7 0x80608aa in rb_gc_force_recycle () #8 0x8060494 in rb_gc_mark () #9 0x8060a36 in rb_gc () #10 0x805f863 in xmalloc () #11 0x8087822 in rb_f_sprintf () #12 0x80654a3 in rb_io_unbuffered () #13 0x8056cb5 in rb_ensure () #14 0x8057142 in rb_ensure () #15 0x80577d4 in rb_ensure () #16 0x8053794 in rb_eval_cmd () #17 0x8055e0a in rb_iterator_p () #18 0x8055f73 in rb_yield () #19 0x8093a1b in rb_ary_each () #20 0x8056cbf in rb_ensure () #21 0x8057142 in rb_ensure () #22 0x80577d4 in rb_ensure () #23 0x8053794 in rb_eval_cmd () #24 0x80529cd in rb_eval_cmd () #25 0x8052302 in rb_eval_cmd () #26 0x8050ab4 in ruby_options () #27 0x8050b90 in ruby_run () #28 0x804f94c in main () strace の結果です。プロセスが止ってしまうので、そこで C-c しています。 write(1, "
  • 0.0KB\n", 28) = 28 write(1, "
  • 0.0KB\n", 28) = 28 brk(0x8108000) = 0x8108000 write(1, "
  • 0.0KB\n", 28) = 28 close(5) = 0 munmap(0x4000b000, 4096) = 0 sigaction(SIGHUP, {SIG_IGN}, {0x8087060, [], SA_STACK|0xda028}) = 0 sigaction(SIGQUIT, {SIG_IGN}, {0x8087060, [], 0x2}) = 0 sigaction(SIGINT, {SIG_IGN}, {0x8087060, [], SA_STACK|SA_NOCLDSTOP|0x5fcd8}) = 0 wait4(6573, [WIFSIGNALED(s) && WTERMSIG(s) == SIGINT], 0, NULL) = 6573 --- SIGINT (Interrupt) --- --- SIGCHLD (Child exited) --- sigaction(SIGHUP, {0x8087060, [], SA_STACK|SA_RESTART|SA_INTERRUPT|SA_ONESHOT|0x7ffdf18}, {SIG_IGN}) = 0 sigaction(SIGQUIT, {0x8087060, [], SA_STACK|SA_NOCLDSTOP|0x5fbca}, {SIG_IGN}) = 0 sigaction(SIGINT, {0x8087060, [], SA_STACK|0xda028}, {SIG_IGN}) = 0 write(1, "
  • 0.0KB\n", 28) = -1 EPIPE (Broken pipe) --- SIGPIPE (Broken pipe) --- sigreturn() = ? (mask now []) sigprocmask(SIG_SETMASK, [], NULL) = 0 write(2, "timesort.rb:81", 14) = 14 write(2, ": ", 2) = 2 write(2, "SIGPIPE", 7) = 7 write(2, " (", 2) = 2 write(2, "SignalException", 15) = 15 write(2, ")\n", 2) = 2 write(2, "\tfrom timesort.rb:78:in `each\'"..., 31) = 31 write(2, "\tfrom timesort.rb:78\n", 21) = 21 munmap(0x4000c000, 4096) = 0 _exit(1) = ? どちらも wait4(2) でプロセスの終了待ちをしていますが、スカッと終わると きは、この wait4(2) に到達していないようです。 -- WATANABE Tetsuya e-mail: Tetsuya_WATANABE@hp.com tetsu@jpn.hp.com