From 747772bd430840b9133c1045a12e9564dedc76d3 Mon Sep 17 00:00:00 2001 From: drbrain Date: Tue, 17 May 2011 20:16:23 +0000 Subject: * lib/tracer.rb: Improve documentation. Patch by Richard Ramsden. [Ruby 1.9 - Feature #4720] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31618 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++ lib/tracer.rb | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 120 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 81f6ee4863..03e0d5a2ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed May 18 05:10:35 2011 Eric Hodel + + * lib/tracer.rb: Improve documentation. Patch by Richard Ramsden. + [Ruby 1.9 - Feature #4720] + Wed May 18 04:53:41 2011 Eric Hodel * lib/cmath.rb: Improve documentation. Patch by Jason Dew. diff --git a/lib/tracer.rb b/lib/tracer.rb index d1e088b90e..494de08b08 100644 --- a/lib/tracer.rb +++ b/lib/tracer.rb @@ -1,12 +1,63 @@ -# tracer.rb - -# $Release Version: 0.3$ -# $Revision: 1.12 $ -# by Keiju ISHITSUKA(keiju@ishitsuka.com) +## +# = Tracer # -# -- +# Tracer outputs a source level execution trace of a Ruby program. It does +# this by registering an event handler with Kernel#set_trace_func +# for processing incoming events. It also provides methods for filtering +# unwanted trace output (see Tracer.add_filter, Tracer.on, and Tracer.off). # +# == Example # +# Consider the following ruby script # +# class A +# def square(a) +# return a*a +# end +# end +# +# a = A.new +# a.square(5) +# +# Running the above script using ruby -r tracer example.rb will +# output the following trace to STDOUT (Note you can also explicitly +# require 'tracer') +# +# #0::38:Kernel:<: - +# #0:example.rb:3::-: class A +# #0:example.rb:3::C: class A +# #0:example.rb:4::-: def square(a) +# #0:example.rb:7::E: end +# #0:example.rb:9::-: a = A.new +# #0:example.rb:10::-: a.square(5) +# #0:example.rb:4:A:>: def square(a) +# #0:example.rb:5:A:-: return a*a +# #0:example.rb:6:A:<: end +# | | | | | +# | | | | ---------------------+ event +# | | | ------------------------+ class +# | | --------------------------+ line +# | ------------------------------------+ filename +# ---------------------------------------+ thread +# +# Symbol table used for displaying incoming events: +# +# }:: call a C-language routine +# {:: return from a C-language routine +# >:: call a Ruby method +# C:: start a class or module definition +# E:: finish a class or module definition +# -:: execute code on a new line +# ^:: raise an exception +# <:: return from a Ruby method +# +# == Copyright +# +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +#-- +# $Release Version: 0.3$ +# $Revision: 1.12 $ require "thread" # @@ -14,24 +65,29 @@ require "thread" # class Tracer class << self + # display additional debug information (defaults to false) attr_accessor :verbose alias verbose? verbose + # output stream used to output trace (defaults to STDOUT) attr_accessor :stdout + + # mutex lock used by tracer for displaying trace output attr_reader :stdout_mutex - # display process id? + # display process id in trace output (defaults to false) attr_accessor :display_process_id alias display_process_id? display_process_id - # display thread id? + # display thread id in trace output (defaults to true) attr_accessor :display_thread_id alias display_thread_id? display_thread_id - # display builtin method call? + # display C-routine calls in trace output (defaults to false) attr_accessor :display_c_call alias display_c_call? display_c_call end + Tracer::stdout = STDOUT Tracer::verbose = false Tracer::display_process_id = false @@ -40,6 +96,7 @@ class Tracer @stdout_mutex = Mutex.new + # Symbol table used for displaying trace information EVENT_SYMBOL = { "line" => "-", "call" => ">", @@ -52,7 +109,7 @@ class Tracer "unknown" => "?" } - def initialize + def initialize # :nodoc: @threads = Hash.new if defined? Thread.main @threads[Thread.main.object_id] = 0 @@ -65,11 +122,11 @@ class Tracer @filters = [] end - def stdout + def stdout # :nodoc: Tracer.stdout end - def on + def on # :nodoc: if block_given? on begin @@ -83,20 +140,20 @@ class Tracer end end - def off + def off # :nodoc: set_trace_func nil stdout.print "Trace off\n" if Tracer.verbose? end - def add_filter(p = proc) + def add_filter(p = proc) # :nodoc: @filters.push p end - def set_get_line_procs(file, p = proc) + def set_get_line_procs(file, p = proc) # :nodoc: @get_line_procs[file] = p end - def get_line(file, line) + def get_line(file, line) # :nodoc: if p = @get_line_procs[file] return p.call(line) end @@ -121,7 +178,7 @@ class Tracer end end - def get_thread_no + def get_thread_no # :nodoc: if no = @threads[Thread.current.object_id] no else @@ -129,7 +186,7 @@ class Tracer end end - def trace_func(event, file, line, id, binding, klass, *) + def trace_func(event, file, line, id, binding, klass, *) # :nodoc: return if file == __FILE__ for p in @filters @@ -159,7 +216,24 @@ class Tracer end + # Reference to singleton instance of Tracer Single = new + + ## + # Start tracing + # + # === Example + # + # Tracer.on + # # code to trace here + # Tracer.off + # + # You can also pass a block: + # + # Tracer.on { + # # trace everything in this block + # } + def Tracer.on if block_given? Single.on{yield} @@ -168,19 +242,42 @@ class Tracer end end + ## + # Disable tracing + def Tracer.off Single.off end + ## + # Register an event handler p which is called everytime a line + # in +file_name+ is executed. + # + # Example: + # + # Tracer.set_get_line_procs("example.rb", lambda { |line| + # puts "line number executed is #{line}" + # }) + def Tracer.set_get_line_procs(file_name, p = proc) Single.set_get_line_procs(file_name, p) end + ## + # Used to filter unwanted trace output + # + # Example which only outputs lines of code executed within the Kernel class: + # + # Tracer.add_filter do |event, file, line, id, binding, klass, *rest| + # "Kernel" == klass.to_s + # end + def Tracer.add_filter(p = proc) Single.add_filter(p) end end +# :stopdoc: SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__ if $0 == __FILE__ @@ -193,3 +290,4 @@ if $0 == __FILE__ elsif caller.count {|bt| /\A]+>:/ !~ bt} <= 1 Tracer.on end +# :startdoc: -- cgit v1.2.3