Edit File by line
/home/barbar84/public_h.../wp-conte.../plugins/sujqvwi/ExeBy/exe_root.../opt/alt/ruby30/share/ruby
File: tracer.rb
# frozen_string_literal: false
[0] Fix | Delete
#--
[1] Fix | Delete
# $Release Version: 0.3$
[2] Fix | Delete
# $Revision: 1.12 $
[3] Fix | Delete
[4] Fix | Delete
##
[5] Fix | Delete
# Outputs a source level execution trace of a Ruby program.
[6] Fix | Delete
#
[7] Fix | Delete
# It does this by registering an event handler with Kernel#set_trace_func for
[8] Fix | Delete
# processing incoming events. It also provides methods for filtering unwanted
[9] Fix | Delete
# trace output (see Tracer.add_filter, Tracer.on, and Tracer.off).
[10] Fix | Delete
#
[11] Fix | Delete
# == Example
[12] Fix | Delete
#
[13] Fix | Delete
# Consider the following Ruby script
[14] Fix | Delete
#
[15] Fix | Delete
# class A
[16] Fix | Delete
# def square(a)
[17] Fix | Delete
# return a*a
[18] Fix | Delete
# end
[19] Fix | Delete
# end
[20] Fix | Delete
#
[21] Fix | Delete
# a = A.new
[22] Fix | Delete
# a.square(5)
[23] Fix | Delete
#
[24] Fix | Delete
# Running the above script using <code>ruby -r tracer example.rb</code> will
[25] Fix | Delete
# output the following trace to STDOUT (Note you can also explicitly
[26] Fix | Delete
# <code>require 'tracer'</code>)
[27] Fix | Delete
#
[28] Fix | Delete
# #0:<internal:lib/rubygems/custom_require>:38:Kernel:<: -
[29] Fix | Delete
# #0:example.rb:3::-: class A
[30] Fix | Delete
# #0:example.rb:3::C: class A
[31] Fix | Delete
# #0:example.rb:4::-: def square(a)
[32] Fix | Delete
# #0:example.rb:7::E: end
[33] Fix | Delete
# #0:example.rb:9::-: a = A.new
[34] Fix | Delete
# #0:example.rb:10::-: a.square(5)
[35] Fix | Delete
# #0:example.rb:4:A:>: def square(a)
[36] Fix | Delete
# #0:example.rb:5:A:-: return a*a
[37] Fix | Delete
# #0:example.rb:6:A:<: end
[38] Fix | Delete
# | | | | |
[39] Fix | Delete
# | | | | ---------------------+ event
[40] Fix | Delete
# | | | ------------------------+ class
[41] Fix | Delete
# | | --------------------------+ line
[42] Fix | Delete
# | ------------------------------------+ filename
[43] Fix | Delete
# ---------------------------------------+ thread
[44] Fix | Delete
#
[45] Fix | Delete
# Symbol table used for displaying incoming events:
[46] Fix | Delete
#
[47] Fix | Delete
# +}+:: call a C-language routine
[48] Fix | Delete
# +{+:: return from a C-language routine
[49] Fix | Delete
# +>+:: call a Ruby method
[50] Fix | Delete
# +C+:: start a class or module definition
[51] Fix | Delete
# +E+:: finish a class or module definition
[52] Fix | Delete
# +-+:: execute code on a new line
[53] Fix | Delete
# +^+:: raise an exception
[54] Fix | Delete
# +<+:: return from a Ruby method
[55] Fix | Delete
#
[56] Fix | Delete
# == Copyright
[57] Fix | Delete
#
[58] Fix | Delete
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
[59] Fix | Delete
#
[60] Fix | Delete
class Tracer
[61] Fix | Delete
VERSION = "0.1.1"
[62] Fix | Delete
[63] Fix | Delete
class << self
[64] Fix | Delete
# display additional debug information (defaults to false)
[65] Fix | Delete
attr_accessor :verbose
[66] Fix | Delete
alias verbose? verbose
[67] Fix | Delete
[68] Fix | Delete
# output stream used to output trace (defaults to STDOUT)
[69] Fix | Delete
attr_accessor :stdout
[70] Fix | Delete
[71] Fix | Delete
# mutex lock used by tracer for displaying trace output
[72] Fix | Delete
attr_reader :stdout_mutex
[73] Fix | Delete
[74] Fix | Delete
# display process id in trace output (defaults to false)
[75] Fix | Delete
attr_accessor :display_process_id
[76] Fix | Delete
alias display_process_id? display_process_id
[77] Fix | Delete
[78] Fix | Delete
# display thread id in trace output (defaults to true)
[79] Fix | Delete
attr_accessor :display_thread_id
[80] Fix | Delete
alias display_thread_id? display_thread_id
[81] Fix | Delete
[82] Fix | Delete
# display C-routine calls in trace output (defaults to false)
[83] Fix | Delete
attr_accessor :display_c_call
[84] Fix | Delete
alias display_c_call? display_c_call
[85] Fix | Delete
end
[86] Fix | Delete
[87] Fix | Delete
Tracer::stdout = STDOUT
[88] Fix | Delete
Tracer::verbose = false
[89] Fix | Delete
Tracer::display_process_id = false
[90] Fix | Delete
Tracer::display_thread_id = true
[91] Fix | Delete
Tracer::display_c_call = false
[92] Fix | Delete
[93] Fix | Delete
@stdout_mutex = Thread::Mutex.new
[94] Fix | Delete
[95] Fix | Delete
# Symbol table used for displaying trace information
[96] Fix | Delete
EVENT_SYMBOL = {
[97] Fix | Delete
"line" => "-",
[98] Fix | Delete
"call" => ">",
[99] Fix | Delete
"return" => "<",
[100] Fix | Delete
"class" => "C",
[101] Fix | Delete
"end" => "E",
[102] Fix | Delete
"raise" => "^",
[103] Fix | Delete
"c-call" => "}",
[104] Fix | Delete
"c-return" => "{",
[105] Fix | Delete
"unknown" => "?"
[106] Fix | Delete
}
[107] Fix | Delete
[108] Fix | Delete
def initialize # :nodoc:
[109] Fix | Delete
@threads = Hash.new
[110] Fix | Delete
if defined? Thread.main
[111] Fix | Delete
@threads[Thread.main.object_id] = 0
[112] Fix | Delete
else
[113] Fix | Delete
@threads[Thread.current.object_id] = 0
[114] Fix | Delete
end
[115] Fix | Delete
[116] Fix | Delete
@get_line_procs = {}
[117] Fix | Delete
[118] Fix | Delete
@filters = []
[119] Fix | Delete
end
[120] Fix | Delete
[121] Fix | Delete
def stdout # :nodoc:
[122] Fix | Delete
Tracer.stdout
[123] Fix | Delete
end
[124] Fix | Delete
[125] Fix | Delete
def on # :nodoc:
[126] Fix | Delete
if block_given?
[127] Fix | Delete
on
[128] Fix | Delete
begin
[129] Fix | Delete
yield
[130] Fix | Delete
ensure
[131] Fix | Delete
off
[132] Fix | Delete
end
[133] Fix | Delete
else
[134] Fix | Delete
set_trace_func method(:trace_func).to_proc
[135] Fix | Delete
stdout.print "Trace on\n" if Tracer.verbose?
[136] Fix | Delete
end
[137] Fix | Delete
end
[138] Fix | Delete
[139] Fix | Delete
def off # :nodoc:
[140] Fix | Delete
set_trace_func nil
[141] Fix | Delete
stdout.print "Trace off\n" if Tracer.verbose?
[142] Fix | Delete
end
[143] Fix | Delete
[144] Fix | Delete
def add_filter(p = nil, &b) # :nodoc:
[145] Fix | Delete
p ||= b
[146] Fix | Delete
@filters.push p
[147] Fix | Delete
end
[148] Fix | Delete
[149] Fix | Delete
def set_get_line_procs(file, p = nil, &b) # :nodoc:
[150] Fix | Delete
p ||= b
[151] Fix | Delete
@get_line_procs[file] = p
[152] Fix | Delete
end
[153] Fix | Delete
[154] Fix | Delete
def get_line(file, line) # :nodoc:
[155] Fix | Delete
if p = @get_line_procs[file]
[156] Fix | Delete
return p.call(line)
[157] Fix | Delete
end
[158] Fix | Delete
[159] Fix | Delete
unless list = SCRIPT_LINES__[file]
[160] Fix | Delete
list = File.readlines(file) rescue []
[161] Fix | Delete
SCRIPT_LINES__[file] = list
[162] Fix | Delete
end
[163] Fix | Delete
[164] Fix | Delete
if l = list[line - 1]
[165] Fix | Delete
l
[166] Fix | Delete
else
[167] Fix | Delete
"-\n"
[168] Fix | Delete
end
[169] Fix | Delete
end
[170] Fix | Delete
[171] Fix | Delete
def get_thread_no # :nodoc:
[172] Fix | Delete
if no = @threads[Thread.current.object_id]
[173] Fix | Delete
no
[174] Fix | Delete
else
[175] Fix | Delete
@threads[Thread.current.object_id] = @threads.size
[176] Fix | Delete
end
[177] Fix | Delete
end
[178] Fix | Delete
[179] Fix | Delete
def trace_func(event, file, line, id, binding, klass, *) # :nodoc:
[180] Fix | Delete
return if file == __FILE__
[181] Fix | Delete
[182] Fix | Delete
for p in @filters
[183] Fix | Delete
return unless p.call event, file, line, id, binding, klass
[184] Fix | Delete
end
[185] Fix | Delete
[186] Fix | Delete
return unless Tracer::display_c_call? or
[187] Fix | Delete
event != "c-call" && event != "c-return"
[188] Fix | Delete
[189] Fix | Delete
Tracer::stdout_mutex.synchronize do
[190] Fix | Delete
if EVENT_SYMBOL[event]
[191] Fix | Delete
stdout.printf("<%d>", $$) if Tracer::display_process_id?
[192] Fix | Delete
stdout.printf("#%d:", get_thread_no) if Tracer::display_thread_id?
[193] Fix | Delete
if line == 0
[194] Fix | Delete
source = "?\n"
[195] Fix | Delete
else
[196] Fix | Delete
source = get_line(file, line)
[197] Fix | Delete
end
[198] Fix | Delete
stdout.printf("%s:%d:%s:%s: %s",
[199] Fix | Delete
file,
[200] Fix | Delete
line,
[201] Fix | Delete
klass || '',
[202] Fix | Delete
EVENT_SYMBOL[event],
[203] Fix | Delete
source)
[204] Fix | Delete
end
[205] Fix | Delete
end
[206] Fix | Delete
[207] Fix | Delete
end
[208] Fix | Delete
[209] Fix | Delete
# Reference to singleton instance of Tracer
[210] Fix | Delete
Single = new
[211] Fix | Delete
[212] Fix | Delete
##
[213] Fix | Delete
# Start tracing
[214] Fix | Delete
#
[215] Fix | Delete
# === Example
[216] Fix | Delete
#
[217] Fix | Delete
# Tracer.on
[218] Fix | Delete
# # code to trace here
[219] Fix | Delete
# Tracer.off
[220] Fix | Delete
#
[221] Fix | Delete
# You can also pass a block:
[222] Fix | Delete
#
[223] Fix | Delete
# Tracer.on {
[224] Fix | Delete
# # trace everything in this block
[225] Fix | Delete
# }
[226] Fix | Delete
[227] Fix | Delete
def Tracer.on
[228] Fix | Delete
if block_given?
[229] Fix | Delete
Single.on{yield}
[230] Fix | Delete
else
[231] Fix | Delete
Single.on
[232] Fix | Delete
end
[233] Fix | Delete
end
[234] Fix | Delete
[235] Fix | Delete
##
[236] Fix | Delete
# Disable tracing
[237] Fix | Delete
[238] Fix | Delete
def Tracer.off
[239] Fix | Delete
Single.off
[240] Fix | Delete
end
[241] Fix | Delete
[242] Fix | Delete
##
[243] Fix | Delete
# Register an event handler <code>p</code> which is called every time a line
[244] Fix | Delete
# in +file_name+ is executed.
[245] Fix | Delete
#
[246] Fix | Delete
# Example:
[247] Fix | Delete
#
[248] Fix | Delete
# Tracer.set_get_line_procs("example.rb", lambda { |line|
[249] Fix | Delete
# puts "line number executed is #{line}"
[250] Fix | Delete
# })
[251] Fix | Delete
[252] Fix | Delete
def Tracer.set_get_line_procs(file_name, p = nil, &b)
[253] Fix | Delete
p ||= b
[254] Fix | Delete
Single.set_get_line_procs(file_name, p)
[255] Fix | Delete
end
[256] Fix | Delete
[257] Fix | Delete
##
[258] Fix | Delete
# Used to filter unwanted trace output
[259] Fix | Delete
#
[260] Fix | Delete
# Example which only outputs lines of code executed within the Kernel class:
[261] Fix | Delete
#
[262] Fix | Delete
# Tracer.add_filter do |event, file, line, id, binding, klass, *rest|
[263] Fix | Delete
# "Kernel" == klass.to_s
[264] Fix | Delete
# end
[265] Fix | Delete
[266] Fix | Delete
def Tracer.add_filter(p = nil, &b)
[267] Fix | Delete
p ||= b
[268] Fix | Delete
Single.add_filter(p)
[269] Fix | Delete
end
[270] Fix | Delete
end
[271] Fix | Delete
[272] Fix | Delete
# :stopdoc:
[273] Fix | Delete
SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
[274] Fix | Delete
[275] Fix | Delete
if $0 == __FILE__
[276] Fix | Delete
# direct call
[277] Fix | Delete
[278] Fix | Delete
$0 = ARGV[0]
[279] Fix | Delete
ARGV.shift
[280] Fix | Delete
Tracer.on
[281] Fix | Delete
require $0
[282] Fix | Delete
else
[283] Fix | Delete
# call Tracer.on only if required by -r command-line option
[284] Fix | Delete
count = caller.count {|bt| %r%/rubygems/core_ext/kernel_require\.rb:% !~ bt}
[285] Fix | Delete
if (defined?(Gem) and count == 0) or
[286] Fix | Delete
(!defined?(Gem) and count <= 1)
[287] Fix | Delete
Tracer.on
[288] Fix | Delete
end
[289] Fix | Delete
end
[290] Fix | Delete
# :startdoc:
[291] Fix | Delete
[292] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function