0001-Added-documentation-for-lib-tracer.rb.patch

Richard Ramsden, 05/17/2011 04:23 PM

Download (6.41 KB)

View differences:

lib/tracer.rb
1
#   tracer.rb -
2
#   	$Release Version: 0.3$
3
#   	$Revision: 1.12 $
4
#   	by Keiju ISHITSUKA(keiju@ishitsuka.com)
1
##
2
# = Tracer
5 3
#
6
# --
4
# Tracer outputs a source level execution trace of a Ruby program. It does this by
5
# registering an event handler with <code>Kernel#set_trace_func</code> for processing incoming events.
6
# It also provides methods for filtering unwanted trace output (see Tracer.add_filter, Tracer.on, and Tracer.off).
7
#
8
# == Example
9
#
10
# Consider the following ruby script
11
#
12
#   class A
13
#     def square(a)
14
#       return a*a
15
#     end
16
#   end
17
#
18
#   a = A.new
19
#   a.square(5)
20
#
21
# Running the above script using <code>ruby -r tracer example.rb</code> will 
22
# output the following trace to STDOUT (Note you can also explicitly <code>require 'tracer'</code>) 
23
#
24
#   #0:<internal:lib/rubygems/custom_require>:38:Kernel:<: -
25
#   #0:example.rb:3::-: class A
26
#   #0:example.rb:3::C: class A
27
#   #0:example.rb:4::-:   def square(a)
28
#   #0:example.rb:7::E: end
29
#   #0:example.rb:9::-: a = A.new
30
#   #0:example.rb:10::-: a.square(5)
31
#   #0:example.rb:4:A:>:   def square(a)
32
#   #0:example.rb:5:A:-:     return a*a
33
#   #0:example.rb:6:A:<:   end
34
#    |  |         | |  | 
35
#    |  |         | |   ---------------------+ event
36
#    |  |         |  ------------------------+ class
37
#    |  |          --------------------------+ line
38
#    |   ------------------------------------+ filename
39
#     ---------------------------------------+ thread
40
#
41
# Symbol table used for displaying incoming events:
7 42
#
43
# * <tt>}</tt> (call a C-language routine) 
44
# * <tt>{</tt> (return from a C-language routine)
45
# * <tt>></tt> (call a Ruby method)
46
# * <tt>C</tt> (start a class or module definition)
47
# * <tt>E</tt> (finish a class or module definition)
48
# * <tt>-</tt> (execute code on a new line)
49
# * <tt>^</tt> (raise an exception)
50
# * <tt><</tt> (return from a Ruby method) 
8 51
#
52
# == Copyright
9 53
#
54
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
55
#
56
# --
57
# $Release Version: 0.3$
58
# $Revision: 1.12 $
10 59
require "thread"
11 60

  
12 61
#
......
14 63
#
15 64
class Tracer
16 65
  class << self
66
    # display additional debug information (defaults to false)
17 67
    attr_accessor :verbose
18 68
    alias verbose? verbose
19 69

  
70
    # output stream used to output trace (defaults to STDOUT)
20 71
    attr_accessor :stdout
72
    
73
    # mutex lock used by tracer for displaying trace output 
21 74
    attr_reader :stdout_mutex
22 75

  
23
    # display process id?
76
    # display process id in trace output (defaults to false)
24 77
    attr_accessor :display_process_id
25 78
    alias display_process_id? display_process_id
26 79

  
27
    # display thread id?
80
    # display thread id in trace output (defaults to true)
28 81
    attr_accessor :display_thread_id
29 82
    alias display_thread_id? display_thread_id
30 83

  
31
    # display builtin method call?
84
    # display C-routine calls in trace output (defaults to false)
32 85
    attr_accessor :display_c_call
33 86
    alias display_c_call? display_c_call
34 87
  end
88

  
35 89
  Tracer::stdout = STDOUT
36 90
  Tracer::verbose = false
37 91
  Tracer::display_process_id = false
......
40 94

  
41 95
  @stdout_mutex = Mutex.new
42 96

  
97
  # Symbol table used for displaying trace information
43 98
  EVENT_SYMBOL = {
44 99
    "line" => "-",
45 100
    "call" => ">",
......
52 107
    "unknown" => "?"
53 108
  }
54 109

  
55
  def initialize
110
  def initialize # :nodoc:
56 111
    @threads = Hash.new
57 112
    if defined? Thread.main
58 113
      @threads[Thread.main.object_id] = 0
......
65 120
    @filters = []
66 121
  end
67 122

  
68
  def stdout
123
  def stdout # :nodoc:
69 124
    Tracer.stdout
70 125
  end
71 126

  
72
  def on
127
  def on # :nodoc:
73 128
    if block_given?
74 129
      on
75 130
      begin
......
83 138
    end
84 139
  end
85 140

  
86
  def off
141
  def off # :nodoc:
87 142
    set_trace_func nil
88 143
    stdout.print "Trace off\n" if Tracer.verbose?
89 144
  end
90 145

  
91
  def add_filter(p = proc)
146
  def add_filter(p = proc) # :nodoc:
92 147
    @filters.push p
93 148
  end
94 149

  
95
  def set_get_line_procs(file, p = proc)
150
  def set_get_line_procs(file, p = proc) # :nodoc:
96 151
    @get_line_procs[file] = p
97 152
  end
98 153

  
99
  def get_line(file, line)
154
  def get_line(file, line) # :nodoc:
100 155
    if p = @get_line_procs[file]
101 156
      return p.call(line)
102 157
    end
......
121 176
    end
122 177
  end
123 178

  
124
  def get_thread_no
179
  def get_thread_no # :nodoc:
125 180
    if no = @threads[Thread.current.object_id]
126 181
      no
127 182
    else
......
129 184
    end
130 185
  end
131 186

  
132
  def trace_func(event, file, line, id, binding, klass, *)
187
  def trace_func(event, file, line, id, binding, klass, *) # :nodoc:
133 188
    return if file == __FILE__
134 189

  
135 190
    for p in @filters
......
159 214

  
160 215
  end
161 216

  
217
  # Reference to singleton instance of Tracer
162 218
  Single = new
219

  
220
  ##
221
  # Start tracing
222
  #
223
  # === Example
224
  #
225
  #   Tracer.on
226
  #   # code to trace here
227
  #   Tracer.off
228
  #
229
  # You can also pass a block:
230
  #
231
  #   Tracer.on {
232
  #     # trace everything in this block
233
  #   }
234

  
163 235
  def Tracer.on
164 236
    if block_given?
165 237
      Single.on{yield}
......
168 240
    end
169 241
  end
170 242

  
243
  ##
244
  # Disable tracing
245

  
171 246
  def Tracer.off
172 247
    Single.off
173 248
  end
174 249

  
250
  ##
251
  # Register an event handler <code>p</code> which is called 
252
  # everytime a line in +file_name+ is executed. 
253
  #
254
  # ==== Example
255
  #   
256
  #   Tracer.set_get_line_procs("example.rb", lambda { |line|
257
  #     puts "line number executed is #{line}"
258
  #   })
259

  
175 260
  def Tracer.set_get_line_procs(file_name, p = proc)
176 261
    Single.set_get_line_procs(file_name, p)
177 262
  end
178 263

  
264
  ##
265
  # Used to filter unwanted trace output 
266
  #
267
  # === Example
268
  #
269
  # Only output lines of code executed within the Kernel class:
270
  #
271
  #   Tracer.add_filter do |event, file, line, id, binding, klass, *rest|
272
  #     "Kernel" == klass.to_s
273
  #   end
274

  
179 275
  def Tracer.add_filter(p = proc)
180 276
    Single.add_filter(p)
181 277
  end
182 278
end
183 279

  
280
# :stopdoc:
184 281
SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
185 282

  
186 283
if $0 == __FILE__
......
193 290
elsif caller.count {|bt| /\A<internal:[^<>]+>:/ !~ bt} <= 1
194 291
  Tracer.on
195 292
end
293
# :startdoc:
196
-