From: keiju@... (Keiju ISHITSUKA) Date: 1997-08-14T17:20:30+09:00 Subject: [ruby-dev:127] tracer けいじゅ@いそうろう.日本ラショナルです. 松本氏はメイルの届かないところにいってしまったので, 返事は来週になると 思いますが, 忘れないようにメイルします. スレッドのプログラムをデバックする時に結構苦労する(子スレッドのどこで エラーが発生したのか分かりずらい)ので, 簡単なトレーサを作ってみました. # ほんとうは, スレッドのプログラムをもう少しデバッグしやすくして欲しい # んですが... で, 幾つか気がついたこと&質問があります. 1. set_trace_funcで呼ばれるprocのthreadがおかしい ある行を実行する前にset_trace_funcで設定されたprocが呼ばれるのですが, 1つ前のthreadで呼ばれています. 2. イベントlineはなぜ全ての実行で発生しない? 時々発生していないことがありますが, 何故でしょう?? 3. IO.readlines()がprivate ruby-1.1a0での話しです. 4. 質問(1) set_trace_funcは, thread毎に設定できるのですか? 実際にスレッド毎に設定 できたもので... require "tracer.rb" Thread.start do Tracer.on ... end 上記のように, あるthreadでトレースをONにするとそのスレッドだけトレース されます... 5. 質問(2) ソースの最後の行を見て頂くと気づくと思うのですが, このファイル (tracer.rb)はrequireしても, コマンドとしても実行でるようにしました. つまり, tracer.rb fooo.rb ... でも実行できますし, require "tracer.rb" ... Tracer.on ... でも実行できます. それで質問というのは, tracer.rb fooo.rb と実行した時, 実際に実行するプログラム(fooo.rb)が fooo.rb で実行されているようにするには, どのような設定が必要なんでしょう? 今は, ARGVと$0だけ再設定しているのですが... -- ここからソース(tracer.rb) class Tracer MY_FILE_NAME_PATTERN = /^tracer\.(rb)?/ EVENT_SYMBOL = { "line" => "-", "call" => ">", "return" => "<", "class" => "C", "end" => "E"} def initialize $threads = Hash.new $sources = Hash.new end def on set_trace_func proc{|event, file, line, id, binding| trace_func event, file, line, id, binding } print "Trace on\n" end def off set_trace_func nil print "Trace off\n" end def get_thread_no unless no = $threads[Thread.current.id] $threads[Thread.current.id] = no = $threads.size end no end def get_line(file, line) unless list = $sources[file] begin f =open(file) $sources[file] = list = f.readlines ensure f.close end end list[line - 1] end def trace_func(event, file, line, id, binding) return if File.basename(file) =~ MY_FILE_NAME_PATTERN Thread.critical = TRUE printf("#%d:%s:%d:%s: %s", get_thread_no, file, line, EVENT_SYMBOL[event], get_line(file, line)) Thread.critical = FALSE end Single = new def Tracer.on Single.on end def Tracer.off Single.off end end if File.basename($0) =~ Tracer::MY_FILE_NAME_PATTERN $0 = ARGV[0] ARGV.shift Tracer.on require $0 end __ ..........................................石塚 圭樹@日本ラショナル... ----------------------------------->> e-mail: keiju@bc.mbn.or.jp <<---