From: "H.Yamamoto" Date: 2005-08-08T21:19:01+09:00 Subject: [ruby-dev:26765] ip_finalize でデバッグモードを解除しないと落ちる問題について 山本です。 tcltklib.c の ip_finalize でデバッグモードを解除しないと 落ちるというのは、ファイナライザが呼ばれる時点で rb_stderr が解放 されてしまっているのではないでしょうか。TYPE(rb_stderr) == 0 と なっているため、後続の関数の TYPE(rb_stderr) == T_FILE が成り立たず、 無限ループになってしまってました。(結果、スタックオーバーフローで落ちる) というか、ファイナライザで ruby コードが走ってもいいんでしょうか? コールバック経由で ruby コードが呼ばれているようだったのですが。 //////////////////////////////////////////////// // とりあえず落ちなくなるパッチ Index: io.c =================================================================== RCS file: /src/ruby/io.c,v retrieving revision 1.375 diff -u -w -b -p -r1.375 io.c --- io.c 27 Jul 2005 07:27:18 -0000 1.375 +++ io.c 8 Aug 2005 11:57:53 -0000 @@ -3934,8 +3934,13 @@ rb_write_error2(mesg, len) const char *mesg; long len; { + if (TYPE(rb_stderr)) { rb_io_write(rb_stderr, rb_str_new(mesg, len)); } + else { + fprintf(mesg, len, 1, stderr); + } +} void rb_write_error(mesg) Index: ext/tk/tcltklib.c =================================================================== RCS file: /src/ruby/ext/tk/tcltklib.c,v retrieving revision 1.36 diff -u -w -b -p -r1.36 tcltklib.c --- ext/tk/tcltklib.c 6 Aug 2005 16:27:12 -0000 1.36 +++ ext/tk/tcltklib.c 8 Aug 2005 11:56:26 -0000 @@ -4278,14 +4278,14 @@ ip_finalize(ip) delete_slaves(ip); /* delete root widget */ -#if 0 +#if 1 DUMP1("check `destroy'"); if (Tcl_GetCommandInfo(ip, "destroy", &info)) { DUMP1("call `destroy'"); Tcl_GlobalEval(ip, "destroy ."); } #endif -#if 1 +#if 0 DUMP1("destroy root widget"); if (tk_stubs_init_p() && Tk_MainWindow(ip) != (Tk_Window)NULL) { DUMP1("call Tk_DestroyWindow"); ////////////////////////// // 結果 E:\ruby-cvs\win32>ruby ..\ruby\runruby.rb --ext=".ext" -- -d -C ..\ruby\ext\tk\s ample binstr_usage.rb (snip) E:/ruby-cvs/win32/.ext/tk.rb:1118: warning: instance variable @tk_cmd_tbl not in itialized tcltklib: finish ip_ruby_cmd_core tcltklib: receiver:TkCore tcltklib: arg:c00000 tcltklib: arg:.w00001.w00002 tcltklib: call ip_ruby_cmd_core E:/ruby-cvs/win32/.ext/tk.rb:1118: warning: instance variable @tk_cmd_tbl not in itialized tcltklib: finish ip_ruby_cmd_core tcltklib: receiver:TkCore tcltklib: arg:c00000 tcltklib: arg:.w00001.w00003 tcltklib: call ip_ruby_cmd_core E:/ruby-cvs/win32/.ext/tk.rb:1118: warning: instance variable @tk_cmd_tbl not in itialized tcltklib: finish ip_ruby_cmd_core tcltklib: receiver:TkCore tcltklib: arg:c00000 tcltklib: arg:.w00001.w00004 tcltklib: call ip_ruby_cmd_core E:/ruby-cvs/win32/.ext/tk.rb:1118: warning: instance variable @tk_cmd_tbl not in itialized tcltklib: finish ip_ruby_cmd_core tcltklib: receiver:TkCore tcltklib: arg:c00000 tcltklib: arg:.w00001 tcltklib: call ip_ruby_cmd_core E:/ruby-cvs/win32/.ext/tk.rb:1118: warning: instance variable @tk_cmd_tbl not in itialized tcltklib: finish ip_ruby_cmd_core tcltklib: receiver:TkCore tcltklib: arg:c00000 tcltklib: arg:. tcltklib: call ip_ruby_cmd_core E:/ruby-cvs/win32/.ext/tk.rb:1118: warning: instance variable @tk_cmd_tbl not in itialized tcltklib: finish ip_ruby_cmd_core tcltklib: check `finalize-hook-proc' tcltklib: call finalize hook proc 'INTERP_FINALIZE_HOOK' tcltklib: check `foreach' & `after' tcltklib: cancel after callbacks tcltklib: finish ip_finalize tcltklib: complete freeing Tcl Interp