Class: Tracer

Inherits:
Object
  • Object
show all
Defined in:
lib/shared.rb,
lib/core_backtracer_locals.rb

Overview

tracer shared for the get_line aspect

Constant Summary collapse

EVENT_SYMBOL =
{
  "line" => "-",
  "call" => ">",
  "return" => "<",
  "class" => "C",
  "end" => "E",
  "c-call" => ">",
  "c-return" => "<",
  "raise" => "R"
}
Single =
new
@@depths =

I think I added this [rdp]

{}
@@last_line =
nil
@@last_file =
nil
@@last_symbol =
nil

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeTracer

Returns a new instance of Tracer.



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/core_backtracer_locals.rb', line 38

def initialize
  @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

.stdoutObject

Returns the value of attribute stdout.



24
25
26
# File 'lib/core_backtracer_locals.rb', line 24

def stdout
  @stdout
end

.verboseObject Also known as: verbose?

Returns the value of attribute verbose.



22
23
24
# File 'lib/core_backtracer_locals.rb', line 22

def verbose
  @verbose
end

Class Method Details

.add_filter(p = proc) ⇒ Object



186
187
188
# File 'lib/core_backtracer_locals.rb', line 186

def Tracer.add_filter(p = proc)
  Single.add_filter(p)
end

.get_line(file, line) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/shared.rb', line 5

def self.get_line(file, line)
  @get_line_procs ||= {}
  if p = @get_line_procs[file]
    return p.call(line)
  end

  unless list = SCRIPT_LINES__[file]
    begin
        raise 'might be a .so file' if file =~ /\.so$/
 f = open(file)
 begin
   SCRIPT_LINES__[file] = list = f.readlines
 ensure
   f.close
 end
    
    rescue
	SCRIPT_LINES__[file] = list = []
    end
  end

  if l = list[line - 1]
    l
  else
    "-\n"
  end
end

.offObject



177
178
179
# File 'lib/core_backtracer_locals.rb', line 177

def Tracer.off
  Single.off
end

.onObject



169
170
171
172
173
174
175
# File 'lib/core_backtracer_locals.rb', line 169

def Tracer.on
  if block_given?
    Single.on{yield}
  else
    Single.on
  end
end

.output_locals(previous_binding, prefix = "\t\t") ⇒ Object



190
191
192
193
194
195
196
197
198
# File 'lib/core_backtracer_locals.rb', line 190

def Tracer.output_locals(previous_binding, prefix="\t\t")
  locals_name = Kernel.eval("local_variables", previous_binding)
  locals = {}
  for name in locals_name do
	locals[name] = Kernel.eval(name, previous_binding)
  end
  
  puts "#{prefix}locals: " + locals.inspect
end

.set_get_line_procs(file_name, p = proc) ⇒ Object



181
182
183
# File 'lib/core_backtracer_locals.rb', line 181

def Tracer.set_get_line_procs(file_name, p = proc)
  Single.set_get_line_procs(file_name, p)
end

Instance Method Details

#add_filter(p = proc) ⇒ Object



74
75
76
# File 'lib/core_backtracer_locals.rb', line 74

def add_filter(p = proc)
  @filters.push p
end

#get_line(file, line) ⇒ Object



82
83
84
# File 'lib/core_backtracer_locals.rb', line 82

def get_line(file, line)
 self.class.get_line(file, line)
end

#get_thread_noObject



87
88
89
90
91
92
93
# File 'lib/core_backtracer_locals.rb', line 87

def get_thread_no
  if no = @threads[Thread.current.object_id]
    no
  else
    @threads[Thread.current.object_id] = @threads.size
  end
end

#offObject



69
70
71
72
# File 'lib/core_backtracer_locals.rb', line 69

def off
  set_trace_func nil
  stdout.print "Trace off\n" if Tracer.verbose?
end

#onObject



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/core_backtracer_locals.rb', line 55

def on
  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 = proc) ⇒ Object



78
79
80
# File 'lib/core_backtracer_locals.rb', line 78

def set_get_line_procs(file, p = proc)
  @get_line_procs[file] = p
end

#stdoutObject



51
52
53
# File 'lib/core_backtracer_locals.rb', line 51

def stdout
  Tracer.stdout
end

#trace_func(event, file, line, id, binding, klass, *nothing) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/core_backtracer_locals.rb', line 100

def trace_func(event, file, line, id, binding, klass, *nothing)
 begin
  return if file == __FILE__

  type = EVENT_SYMBOL[event] # "<" or ">"
  thread_no = get_thread_no
  Thread.current['backtrace'] ||= []
  @@depths[thread_no] ||= 0
  Thread.current['backtrace'] << nil if Thread.current['backtrace'].length  < (@@depths[thread_no] ) # pad it :)
  if type == ">"
    @@depths[thread_no] += 1
  elsif type == "<"
    @@depths[thread_no] -= 1
  end

  for p in @filters
    return unless p.call event, file, line, id, binding, klass
  end
  return if file.include? 'ruby-debug' # debugger output

  saved_crit = Thread.critical
  Thread.critical = true
  # TODO only do the backtrace if last command was 'raise'
  if type == 'R'
       Thread.current['backtrace'][@@depths[thread_no] - 1] = [[file, line], [], binding]
       Thread.current['backtrace'] = Thread.current['backtrace'][0..@@depths[thread_no]] # clear old stuffs
  end

  if [file, line] != @@last_line # for output sake [not output too many lines]
    if @@last_symbol == '>' # then we need to add to the backtrace--we've advanced down a call in the callstack and can now glean its variables' values
       previous_frame_binding = Debugger.current_context.frame_binding(2)
collected = []
       args = Debugger.current_context.frame_args 1 rescue nil # maybe it had no arguments [ltodo check]

if args
  for arg in args
value =  eval(arg, previous_frame_binding)
collected << [arg, value]
  end 
else
  print "WEIRD--please report err spot 1, how to reproduce"
       end

       print 'args were ', collected.inspect, "\n" if $VERBOSE # we still collect them for the end backtrace if !$VERBOSE

Thread.current['backtrace'][@@depths[thread_no] - 1] = [[@@last_file, @@last_line], collected, previous_frame_binding]
    end
  end

  out = " |" * @@depths[thread_no] + sprintf("#%d:%s:%d:%s:%s: %s",
     get_thread_no,
     file,
     line,
     klass || '',
     type,
     get_line(file, line))

 print out if $print_trace || $VERBOSE
 @@last_line =  line
 @@last_file = file
 @@last_symbol = type

 Thread.critical = saved_crit
 rescue Exception => e
	# TODO investigate print "BAD" + e.to_s + e.backtrace.inspect
 end
end