mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
6e1b572364
commit
747772bd43
2 changed files with 120 additions and 17 deletions
|
@ -1,3 +1,8 @@
|
|||
Wed May 18 05:10:35 2011 Eric Hodel <drbrain@segment7.net>
|
||||
|
||||
* lib/tracer.rb: Improve documentation. Patch by Richard Ramsden.
|
||||
[Ruby 1.9 - Feature #4720]
|
||||
|
||||
Wed May 18 04:53:41 2011 Eric Hodel <drbrain@segment7.net>
|
||||
|
||||
* lib/cmath.rb: Improve documentation. Patch by Jason Dew.
|
||||
|
|
132
lib/tracer.rb
132
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 <code>Kernel#set_trace_func</code>
|
||||
# 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 <code>ruby -r tracer example.rb</code> will
|
||||
# output the following trace to STDOUT (Note you can also explicitly
|
||||
# <code>require 'tracer'</code>)
|
||||
#
|
||||
# #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:
|
||||
#
|
||||
# <tt>}</tt>:: call a C-language routine
|
||||
# <tt>{</tt>:: return from a C-language routine
|
||||
# <tt>></tt>:: call a Ruby method
|
||||
# <tt>C</tt>:: start a class or module definition
|
||||
# <tt>E</tt>:: finish a class or module definition
|
||||
# <tt>-</tt>:: execute code on a new line
|
||||
# <tt>^</tt>:: raise an exception
|
||||
# <tt><</tt>:: 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 <code>p</code> 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<internal:[^<>]+>:/ !~ bt} <= 1
|
||||
Tracer.on
|
||||
end
|
||||
# :startdoc:
|
||||
|
|
Loading…
Reference in a new issue