Class: Tracer
- Inherits:
-
Object
- Object
- Tracer
- Defined in:
- lib/tracer.rb
Overview
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:<internal:lib/rubygems/custom_require>: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([email protected])
Constant Summary collapse
- VERSION =
"0.1.1"
- EVENT_SYMBOL =
Symbol table used for displaying trace information
{ "line" => "-", "call" => ">", "return" => "<", "class" => "C", "end" => "E", "raise" => "^", "c-call" => "}", "c-return" => "{", "unknown" => "?" }
- Single =
Reference to singleton instance of Tracer
new
Class Attribute Summary collapse
-
.display_c_call ⇒ Object
(also: display_c_call?)
display C-routine calls in trace output (defaults to false).
-
.display_process_id ⇒ Object
(also: display_process_id?)
display process id in trace output (defaults to false).
-
.display_thread_id ⇒ Object
(also: display_thread_id?)
display thread id in trace output (defaults to true).
-
.stdout ⇒ Object
output stream used to output trace (defaults to STDOUT).
-
.stdout_mutex ⇒ Object
readonly
mutex lock used by tracer for displaying trace output.
-
.verbose ⇒ Object
(also: verbose?)
display additional debug information (defaults to false).
Class Method Summary collapse
-
.add_filter(p = nil, &b) ⇒ Object
Used to filter unwanted trace output.
-
.off ⇒ Object
Disable tracing.
-
.on ⇒ Object
Start tracing.
-
.set_get_line_procs(file_name, p = nil, &b) ⇒ Object
Register an event handler
p
which is called every time a line infile_name
is executed.
Instance Method Summary collapse
-
#add_filter(p = nil, &b) ⇒ Object
:nodoc:.
-
#get_line(file, line) ⇒ Object
:nodoc:.
-
#get_thread_no ⇒ Object
:nodoc:.
-
#initialize ⇒ Tracer
constructor
:nodoc:.
-
#off ⇒ Object
:nodoc:.
-
#on ⇒ Object
:nodoc:.
-
#set_get_line_procs(file, p = nil, &b) ⇒ Object
:nodoc:.
-
#stdout ⇒ Object
:nodoc:.
-
#trace_func(event, file, line, id, binding, klass) ⇒ Object
:nodoc:.
Constructor Details
#initialize ⇒ Tracer
:nodoc:
110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/tracer.rb', line 110 def initialize # :nodoc: @threads = Hash.new if defined? Thread.main @threads[Thread.main.object_id] = 0 else @threads[Thread.current.object_id] = 0 end @get_line_procs = {} @filters = [] end |
Class Attribute Details
.display_c_call ⇒ Object Also known as: display_c_call?
display C-routine calls in trace output (defaults to false)
85 86 87 |
# File 'lib/tracer.rb', line 85 def display_c_call @display_c_call end |
.display_process_id ⇒ Object Also known as: display_process_id?
display process id in trace output (defaults to false)
77 78 79 |
# File 'lib/tracer.rb', line 77 def display_process_id @display_process_id end |
.display_thread_id ⇒ Object Also known as: display_thread_id?
display thread id in trace output (defaults to true)
81 82 83 |
# File 'lib/tracer.rb', line 81 def display_thread_id @display_thread_id end |
.stdout ⇒ Object
output stream used to output trace (defaults to STDOUT)
71 72 73 |
# File 'lib/tracer.rb', line 71 def stdout @stdout end |
.stdout_mutex ⇒ Object (readonly)
mutex lock used by tracer for displaying trace output
74 75 76 |
# File 'lib/tracer.rb', line 74 def stdout_mutex @stdout_mutex end |
.verbose ⇒ Object Also known as: verbose?
display additional debug information (defaults to false)
67 68 69 |
# File 'lib/tracer.rb', line 67 def verbose @verbose end |
Class Method Details
.add_filter(p = nil, &b) ⇒ Object
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
268 269 270 271 |
# File 'lib/tracer.rb', line 268 def Tracer.add_filter(p = nil, &b) p ||= b Single.add_filter(p) end |
.off ⇒ Object
Disable tracing
240 241 242 |
# File 'lib/tracer.rb', line 240 def Tracer.off Single.off end |
.on ⇒ Object
229 230 231 232 233 234 235 |
# File 'lib/tracer.rb', line 229 def Tracer.on if block_given? Single.on{yield} else Single.on end end |
.set_get_line_procs(file_name, p = nil, &b) ⇒ Object
Register an event handler p
which is called every time a line in file_name
is executed.
Example:
Tracer.set_get_line_procs("example.rb", lambda { |line|
puts "line number executed is #{line}"
})
254 255 256 257 |
# File 'lib/tracer.rb', line 254 def Tracer.set_get_line_procs(file_name, p = nil, &b) p ||= b Single.set_get_line_procs(file_name, p) end |
Instance Method Details
#add_filter(p = nil, &b) ⇒ Object
:nodoc:
146 147 148 149 |
# File 'lib/tracer.rb', line 146 def add_filter(p = nil, &b) # :nodoc: p ||= b @filters.push p end |
#get_line(file, line) ⇒ Object
:nodoc:
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/tracer.rb', line 156 def get_line(file, line) # :nodoc: if p = @get_line_procs[file] return p.call(line) end unless list = SCRIPT_LINES__[file] list = File.readlines(file) rescue [] SCRIPT_LINES__[file] = list end if l = list[line - 1] l else "-\n" end end |
#get_thread_no ⇒ Object
:nodoc:
173 174 175 176 177 178 179 |
# File 'lib/tracer.rb', line 173 def get_thread_no # :nodoc: if no = @threads[Thread.current.object_id] no else @threads[Thread.current.object_id] = @threads.size end end |
#off ⇒ Object
:nodoc:
141 142 143 144 |
# File 'lib/tracer.rb', line 141 def off # :nodoc: set_trace_func nil stdout.print "Trace off\n" if Tracer.verbose? end |
#on ⇒ Object
:nodoc:
127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/tracer.rb', line 127 def on # :nodoc: if block_given? on begin yield ensure off end else set_trace_func method(:trace_func).to_proc stdout.print "Trace on\n" if Tracer.verbose? end end |
#set_get_line_procs(file, p = nil, &b) ⇒ Object
:nodoc:
151 152 153 154 |
# File 'lib/tracer.rb', line 151 def set_get_line_procs(file, p = nil, &b) # :nodoc: p ||= b @get_line_procs[file] = p end |
#stdout ⇒ Object
:nodoc:
123 124 125 |
# File 'lib/tracer.rb', line 123 def stdout # :nodoc: Tracer.stdout end |
#trace_func(event, file, line, id, binding, klass) ⇒ Object
:nodoc:
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/tracer.rb', line 181 def trace_func(event, file, line, id, binding, klass, *) # :nodoc: return if file == __FILE__ for p in @filters return unless p.call event, file, line, id, binding, klass end return unless Tracer::display_c_call? or event != "c-call" && event != "c-return" Tracer::stdout_mutex.synchronize do if EVENT_SYMBOL[event] stdout.printf("<%d>", $$) if Tracer::display_process_id? stdout.printf("#%d:", get_thread_no) if Tracer::display_thread_id? if line == 0 source = "?\n" else source = get_line(file, line) end stdout.printf("%s:%d:%s:%s: %s", file, line, klass || '', EVENT_SYMBOL[event], source) end end end |