summaryrefslogtreecommitdiff
path: root/lib/tracer.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tracer.rb')
-rw-r--r--lib/tracer.rb75
1 files changed, 75 insertions, 0 deletions
diff --git a/lib/tracer.rb b/lib/tracer.rb
new file mode 100644
index 0000000000..d37339fd62
--- /dev/null
+++ b/lib/tracer.rb
@@ -0,0 +1,75 @@
+class Tracer
+ MY_FILE_NAME_PATTERN = /^tracer\.(rb)?/
+ Threads = Hash.new
+ Sources = Hash.new
+
+ EVENT_SYMBOL = {
+ "line" => "-",
+ "call" => ">",
+ "return" => "<",
+ "class" => "C",
+ "end" => "E"}
+
+ 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]
+ f =open(file)
+ begin
+ 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.shift
+
+ Tracer.on
+ load $0
+else
+ Tracer.on
+end