From: "門脇 修司" Date: 2010-01-22T19:44:18+09:00 Subject: [ruby-list:46803] TkTable.rbで"[BUG] Segmentaion fauilt"発生 門脇と申します。 Ruby/Tkを使ってWindows上で動くクライアントプログラムを 作っています。 それまで順調に機能追加できていたものが、なんの拍子か Segmentaion faultが発生するようになってしまいました。 環境: Windows XP (SP3) ruby 1.8.7 (2009-06-12 patchlevel 174) [i386-mswin32] (ActiveScriptRuby 1.8.7(p174) with-winsock2を使用) ActiveState ActiveTcl 8.5.8.0.291595 スクリプトを実行させると次のようなメッセージが表示され 終了してしまいます。 1 D:\X\SysproEternus\demoA>demoa5-2.rb 2 "ruby 1.8.7 (2009-06-12 patchlevel 174) [i386-mswin32]" 3 C:/Program Files/ruby-1.8/lib/ruby/1.8/tkextlib/tktable/tktable.rb:421: [BUG] Se 4 gmentation fault 5 ruby 1.8.7 (2009-06-12 patchlevel 174) [i386-mswin32] 6 7 8 This application has requested the Runtime to terminate it in an unusual way. 9 Please contact the application's support team for more information. 10 11 D:\X\SysproEternus\demoA> (この2行目はスクリプト先頭部分にある"p RUBY_DESCRIPTION"の結果です) 「tktable.rb:421: [BUG]」の部分に表示されるライン番号は下(↓)に 示します再現方法によって変わります。 再現させるための最小限のコードは未だ発見できていません。すみません。 再現させるためのスクリプト修正には何通りかあります。 その1 問題のないスクリプトのTk::TkTable.newのパラメタに「foreground 'black'」を 追加する。 "tktable.rb:421: [BUG]"と表示されます。 1 @tktable = Tk::TkTable.new(@cvs) {|t| 2 rows num_rows 3 cols num_cols 4 ... (中略) ... 5 state 'disabled' 6 foreground 'black' # ←この行を追加する 7 x=TkcWindow.new(cvs, 5, ypos, 'window'=>t, 'anchor'=>'nw'),lower 8 } しかし、この1行を追加しても、別の箇所のTkcLine.newを二つ無効に するとSegmentation faultは発生しなくなります。 その2 問題のないスクリプトのifの書き方を変えると発生します。 (上記その1のTkcLine.newは有効にしたままです) "tktable.rb:372: [BUG]"と表示されます。 1 cvs = TkCanvas.new(cf) {|c| 2 ... (中略) ... 3 } 4 cvs.bind('1', proc{|x,y| itemStartDrag cvs,x,y}, '%x %y') 5 def itemStartDrag(c,x,y) 6 # ドラッグされたオブジェクトを最前面にする 7 STDERR.print '...enter itemStartDrag' 8 $lastX = c.canvasx(x) 9 $lastY = c.canvasy(y) 10 c.gettags('current').each {|t| 11 t.raise if t!='all' && t!='current' 12 } 13 STDERR.print '...exit itemStartDrag' 14 end この11行目を書き換えて次のようにします。 1 cvs = TkCanvas.new(cf) {|c| 2 ... (中略) ... 3 } 4 cvs.bind('1', proc{|x,y| itemStartDrag cvs,x,y}, '%x %y') 5 def itemStartDrag(c,x,y) 6 # ドラッグされたオブジェクトを最前面にする 7 STDERR.print '...enter itemStartDrag' 8 $lastX = c.canvasx(x) 9 $lastY = c.canvasy(y) 10 c.gettags('current').each {|t| 11 next if t=='all' !! t=='current' 12 t.raise 13 } 14 STDERR.print '...exit itemStartDrag' 15 end この状態(書き換えた後)でスクリプト先頭の"p RUBY_DESCRIPTION"を コメントにするとsegmentation faultは発生しません。 方法1からはキャンバス上のウィジットが多すぎたのかとも 考えましたが、方法2をみて多すぎたというわけではないなと 考え直しています。 Segmentation faultで示されるラインはクラスは違いますが どちらも次の一行があります。 _setup_subst_table(KEY_TBL, PROC_TBL); Tclの少し前のものでも同じようにsegmentation faultが発生します。 (ActiveState ActiveTcl 8.5.7.1.291226で実行しました) アドバイスいただけたら幸いです。