ruby-debug 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +1 -1
- data/ext/ruby_debug.c +258 -201
- data/lib/ruby-debug.rb +379 -363
- metadata +2 -2
data/lib/ruby-debug.rb
CHANGED
@@ -19,8 +19,8 @@ module Debugger
|
|
19
19
|
return if Thread.critical
|
20
20
|
return if @locker == Thread.current
|
21
21
|
while (Thread.critical = true; @locked)
|
22
|
-
|
23
|
-
|
22
|
+
@waiting.push Thread.current
|
23
|
+
Thread.stop
|
24
24
|
end
|
25
25
|
@locked = true
|
26
26
|
@locker = Thread.current
|
@@ -32,7 +32,7 @@ module Debugger
|
|
32
32
|
return if Thread.critical
|
33
33
|
return unless @locked
|
34
34
|
unless @locker == Thread.current
|
35
|
-
|
35
|
+
raise RuntimeError, "unlocked by other"
|
36
36
|
end
|
37
37
|
Thread.critical = true
|
38
38
|
t = @waiting.shift
|
@@ -56,16 +56,16 @@ module Debugger
|
|
56
56
|
begin
|
57
57
|
require 'readline'
|
58
58
|
def readline(prompt, hist)
|
59
|
-
|
59
|
+
Readline::readline(prompt, hist)
|
60
60
|
end
|
61
61
|
rescue LoadError
|
62
62
|
def readline(prompt, hist)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
63
|
+
STDOUT.print prompt
|
64
|
+
STDOUT.flush
|
65
|
+
line = STDIN.gets
|
66
|
+
exit unless line
|
67
|
+
line.chomp!
|
68
|
+
line
|
69
69
|
end
|
70
70
|
USE_READLINE = false
|
71
71
|
end
|
@@ -85,17 +85,17 @@ module Debugger
|
|
85
85
|
fs = frames.size
|
86
86
|
tb = caller(0)[-fs..-1]
|
87
87
|
if tb
|
88
|
-
|
89
|
-
|
90
|
-
|
88
|
+
for i in tb
|
89
|
+
stdout.printf "\tfrom %s\n", i
|
90
|
+
end
|
91
91
|
end
|
92
92
|
end
|
93
|
-
|
93
|
+
|
94
94
|
def at_tracing(file, line)
|
95
95
|
if Debugger.trace_proc
|
96
|
-
|
96
|
+
Debugger.trace_proc.call(self.thnum, file, line)
|
97
97
|
else
|
98
|
-
|
98
|
+
stdout.puts sprintf("Tracing(%d):%s:%s %s", self.thnum, file, line, line_at(file, line))
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
@@ -105,213 +105,228 @@ module Debugger
|
|
105
105
|
binding_file = file
|
106
106
|
binding_line = line
|
107
107
|
previous_line = nil
|
108
|
-
stdout.printf "%s:%d
|
108
|
+
stdout.printf "%s:%d: %s", binding_file, binding_line, line_at(binding_file, binding_line)
|
109
109
|
display_expressions(binding)
|
110
110
|
prompt = true
|
111
111
|
while prompt and input = readline("(rdb:%d) " % Debugger.thnum, true)
|
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
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
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
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
112
|
+
catch(:debug_error) do
|
113
|
+
next if input == ''
|
114
|
+
|
115
|
+
case input
|
116
|
+
when /^\s*s(?:tep)?(?:\s+(\d+))?$/
|
117
|
+
self.stop_next = $1 ? $1.to_i : 1
|
118
|
+
prompt = false
|
119
|
+
|
120
|
+
when /^\s*c(?:ont)?$|^\s*r(?:un)?$/
|
121
|
+
prompt = false
|
122
|
+
|
123
|
+
when /^\s*v(?:ar)?\s+/
|
124
|
+
debug_variable_info($', binding)
|
125
|
+
|
126
|
+
when /^\s*w(?:here)?$/, /^\s*f(?:rame)?$/
|
127
|
+
display_frames(frame_pos)
|
128
|
+
|
129
|
+
when /^\s*l(?:ist)?(?:\s+(.+))?$/
|
130
|
+
if not $1
|
131
|
+
b = previous_line ? previous_line + 10 : binding_line - 5
|
132
|
+
e = b + 9
|
133
|
+
elsif $1 == '-'
|
134
|
+
b = previous_line ? previous_line - 10 : binding_line - 5
|
135
|
+
e = b + 9
|
136
|
+
else
|
137
|
+
b, e = $1.split(/[-,]/)
|
138
|
+
if e
|
139
|
+
b = b.to_i
|
140
|
+
e = e.to_i
|
141
|
+
else
|
142
|
+
b = b.to_i - 5
|
143
|
+
e = b + 9
|
144
|
+
end
|
145
|
+
end
|
146
|
+
previous_line = b
|
147
|
+
display_list(b, e, binding_file, binding_line)
|
148
|
+
|
149
|
+
when /^\s*n(?:ext)?(?:\s+(\d+))?$/
|
150
|
+
steps = $1 ? $1.to_i : 1
|
151
|
+
self.step_over steps, self.frames.size - frame_pos
|
152
|
+
prompt = false
|
153
|
+
|
154
|
+
when /^\s*up(?:\s+(\d+))?$/
|
155
|
+
previous_line = nil
|
156
|
+
frame_pos += $1 ? $1.to_i : 1
|
157
|
+
if frame_pos >= self.frames.size
|
158
|
+
frame_pos = self.frames.size - 1
|
159
|
+
stdout.puts "At toplevel"
|
160
|
+
end
|
161
|
+
frame = self.frames[frame_pos]
|
162
|
+
binding, binding_file, binding_line = frame.binding, frame.file, frame.line
|
163
|
+
stdout.print format_frame(frame, frame_pos)
|
164
|
+
|
165
|
+
when /^\s*down(?:\s+(\d+))?$/
|
166
|
+
previous_line = nil
|
167
|
+
frame_pos -= $1 ? $1.to_i : 1
|
168
|
+
if frame_pos < 0
|
169
|
+
frame_pos = 0
|
170
|
+
stdout.print "At stack bottom\n"
|
171
|
+
end
|
172
|
+
frame = self.frames[frame_pos]
|
173
|
+
binding, binding_file, binding_line = frame.binding, frame.file, frame.line
|
174
|
+
stdout.print format_frame(frame, frame_pos)
|
175
|
+
|
176
|
+
when /^\s*fin(?:ish)?$/
|
177
|
+
if frame_pos == self.frames.size
|
178
|
+
stdout.print "\"finish\" not meaningful in the outermost frame.\n"
|
179
|
+
else
|
180
|
+
self.stop_frame = self.frames.size - frame_pos
|
181
|
+
frame_pos = 0
|
182
|
+
prompt = false
|
183
|
+
end
|
184
|
+
|
185
|
+
when /^\s*b(?:reak)?\s+(?:(.+):)?([^.:\s]+)\s*(?:\sif\s+(.+))?$/
|
186
|
+
pos = $2
|
187
|
+
expr = $3
|
188
|
+
if $1
|
189
|
+
klass = debug_silent_eval($1, binding)
|
190
|
+
if klass && !klass.kind_of?(Module)
|
191
|
+
stdout.puts "Unknown class #$1"
|
192
|
+
throw :debug_error
|
193
|
+
end
|
194
|
+
klass = klass.name if klass
|
195
|
+
file = $1
|
196
|
+
end
|
197
|
+
if pos =~ /^\d+$/
|
198
|
+
pname = pos
|
199
|
+
pos = pos.to_i
|
200
|
+
else
|
201
|
+
pname = pos = pos.intern.id2name
|
202
|
+
end
|
203
|
+
Debugger.add_breakpoint klass || file, pos, expr
|
204
|
+
stdout.printf "Set breakpoint %d at %s:%s\n", Debugger.breakpoints.size, klass || file, pname
|
205
|
+
|
206
|
+
when /^\s*b(?:reak)?\s+(.+)[#.]([^.:\s]+)(?:\s+if\s+(.+))?$/
|
207
|
+
pos = $2.intern.id2name
|
208
|
+
expr = $3
|
209
|
+
klass = debug_eval($1, binding)
|
210
|
+
if klass.nil? || !klass.kind_of?(Module)
|
211
|
+
stdout.puts "Unknown class #$1"
|
212
|
+
throw :debug_error
|
213
|
+
end
|
214
|
+
Debugger.add_breakpoint klass.name, pos, expr
|
215
|
+
stdout.printf "Set breakpoint %d at %s.%s\n", Debugger.breakpoints.size, klass, pos
|
216
|
+
|
217
|
+
when /^\s*b(?:reak)?$/
|
218
|
+
unless Debugger.breakpoints.empty?
|
219
|
+
stdout.print "Breakpoints:\n"
|
220
|
+
Debugger.breakpoints.each_with_index do |b, n|
|
221
|
+
if b.expr.nil?
|
222
|
+
stdout.printf " %d %s:%s\n", n+1, b.source, b.pos
|
223
|
+
else
|
224
|
+
stdout.printf " %d %s:%s if %s\n", n+1, b.source, b.pos, b.expr
|
225
|
+
end
|
226
|
+
end
|
227
|
+
stdout.puts
|
228
|
+
else
|
229
|
+
stdout.print "No breakpoints\n"
|
230
|
+
end
|
231
|
+
when /^\s*del(?:ete)?(?:\s+(\d+))?$/
|
232
|
+
pos = $1
|
233
|
+
unless pos
|
234
|
+
input = readline("Clear all breakpoints? (y/n) ", false)
|
235
|
+
if input == "y"
|
236
|
+
Debugger.breakpoints.clear
|
237
|
+
end
|
238
|
+
else
|
239
|
+
pos = pos.to_i
|
240
|
+
unless Debugger.breakpoints.delete_at(pos-1)
|
241
|
+
stdout.printf "Breakpoint %d is not defined\n", pos
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
when /^\s*th(?:read)?\s+/
|
246
|
+
if Debugger.debug_thread_info($') == :cont
|
247
|
+
prompt = false
|
248
|
+
end
|
249
|
+
|
250
|
+
when /^\s*m(?:ethod)?\s+/
|
251
|
+
debug_method_info($', binding)
|
252
|
+
|
253
|
+
when /^\s*pp\s+/
|
254
|
+
PP.pp(debug_eval($', binding), stdout) rescue stdout.puts $!.message
|
255
|
+
|
256
|
+
when /^\s*p\s+/
|
257
|
+
stdout.printf "%s\n", debug_eval($', binding).inspect
|
258
|
+
|
259
|
+
when /^\s*h(?:elp)?$/
|
260
|
+
debug_print_help()
|
261
|
+
|
262
|
+
when /^\s*q(?:uit)?$/
|
263
|
+
input = readline("Really quit? (y/n) ", false)
|
264
|
+
if input == "y"
|
265
|
+
exit! # exit -> exit!: No graceful way to stop threads...
|
266
|
+
end
|
267
|
+
|
268
|
+
when /^\s*disp(?:lay)?\s+(.+)$/
|
269
|
+
exp = $1
|
270
|
+
display.push [true, exp]
|
271
|
+
stdout.printf "%d: ", display.size
|
272
|
+
display_expression(exp, binding)
|
273
|
+
|
274
|
+
when /^\s*disp(?:lay)?$/
|
275
|
+
display_expressions(binding)
|
276
|
+
|
277
|
+
when /^\s*undisp(?:lay)?(?:\s+(\d+))?$/
|
278
|
+
pos = $1
|
279
|
+
unless pos
|
280
|
+
input = readline("Clear all expressions? (y/n) ", false)
|
281
|
+
if input == "y"
|
282
|
+
for d in display
|
283
|
+
d[0] = false
|
284
|
+
end
|
285
|
+
end
|
286
|
+
else
|
287
|
+
pos = pos.to_i
|
288
|
+
if display[pos-1]
|
289
|
+
display[pos-1][0] = false
|
290
|
+
else
|
291
|
+
stdout.printf "Display expression %d is not defined\n", pos
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
when /^\s*cat(?:ch)?(?:\s+(.+))?$/
|
296
|
+
if $1
|
297
|
+
excn = $1
|
298
|
+
if excn == 'off'
|
299
|
+
Debugger.catchpoint = nil
|
300
|
+
stdout.print "Clear catchpoint.\n"
|
301
|
+
else
|
302
|
+
Debugger.catchpoint = excn
|
303
|
+
stdout.printf "Set catchpoint %s.\n", excn
|
304
|
+
end
|
305
|
+
else
|
306
|
+
if Debugger.catchpoint
|
307
|
+
stdout.printf "Catchpoint %s.\n", Debugger.catchpoint
|
308
|
+
else
|
309
|
+
stdout.print "No catchpoint.\n"
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
when /^\s*tr(?:ace)?(?:\s+(on|off))?(?:\s+(all))?$/
|
314
|
+
if defined?( $2 )
|
315
|
+
Debugger.tracing = $1 == 'on'
|
316
|
+
elsif defined?( $1 )
|
317
|
+
self.tracing = $1 == 'on'
|
318
|
+
end
|
319
|
+
if Debugger.tracing || self.tracing
|
320
|
+
stdout.print "Trace on.\n"
|
321
|
+
else
|
322
|
+
stdout.print "Trace off.\n"
|
323
|
+
end
|
324
|
+
|
325
|
+
else
|
326
|
+
v = debug_eval(input, binding)
|
327
|
+
stdout.printf "%s\n", v.inspect
|
328
|
+
end
|
329
|
+
end
|
315
330
|
end
|
316
331
|
MUTEX.unlock
|
317
332
|
Debugger.resume
|
@@ -319,54 +334,55 @@ module Debugger
|
|
319
334
|
|
320
335
|
def debug_print_help
|
321
336
|
stdout.print <<EOHELP
|
322
|
-
|
337
|
+
ruby-debug help v.#{Debugger::VERSION}
|
323
338
|
Commands
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
339
|
+
b[reak] [file|class:]<line|method> [if expr]
|
340
|
+
b[reak] [class.]<line|method> [if expr]
|
341
|
+
set breakpoint to some position,
|
342
|
+
optionally if expr == true
|
343
|
+
cat[ch] <an Exception> set catchpoint to an exception
|
344
|
+
cat[ch] show catchpoint
|
345
|
+
disp[lay] <expression> add expression into display expression list
|
346
|
+
undisp[lay][ nnn] delete one particular or all display expressions
|
347
|
+
b[reak] list breakpoints
|
348
|
+
del[ete][ nnn] delete some or all breakpoints
|
349
|
+
c[ont] run until program ends or hit breakpoint
|
350
|
+
r[un] alias for cont
|
351
|
+
s[tep][ nnn] step (into methods) one line or till line nnn
|
352
|
+
n[ext][ nnn] go over one line or till line nnn
|
353
|
+
w[here] display frames
|
354
|
+
f[rame] alias for where
|
355
|
+
l[ist][ (-|nn-mm)] list program, - list backwards, nn-mm list given lines
|
356
|
+
up[ nn] move to higher frame
|
357
|
+
down[ nn] move to lower frame
|
358
|
+
fin[ish] return to outer frame
|
359
|
+
q[uit] exit from debugger
|
360
|
+
v[ar] g[lobal] show global variables
|
361
|
+
v[ar] l[ocal] show local variables
|
362
|
+
v[ar] i[nstance] <object> show instance variables of object
|
363
|
+
v[ar] c[onst] <object> show constants of object
|
364
|
+
m[ethod] i[nstance] <obj> show methods of object
|
365
|
+
m[ethod] <class|module> show instance methods of class or module
|
366
|
+
th[read] l[ist] list all threads
|
367
|
+
th[read] c[ur[rent]] show current thread
|
368
|
+
th[read] [sw[itch]] <nnn> switch thread context to nnn
|
369
|
+
th[read] stop <nnn> stop thread nnn
|
370
|
+
th[read] resume <nnn> resume thread nnn
|
371
|
+
p expression evaluate expression and print its value
|
372
|
+
pp expression evaluate expression and print its value
|
373
|
+
h[elp] print this help
|
374
|
+
<everything else> evaluate
|
359
375
|
EOHELP
|
360
376
|
end
|
361
377
|
|
362
378
|
def display_expressions(binding)
|
363
379
|
n = 1
|
364
380
|
for d in display
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
381
|
+
if d[0]
|
382
|
+
stdout.printf "%d: ", n
|
383
|
+
display_expression(d[1], binding)
|
384
|
+
end
|
385
|
+
n += 1
|
370
386
|
end
|
371
387
|
end
|
372
388
|
|
@@ -376,96 +392,96 @@ EOHELP
|
|
376
392
|
|
377
393
|
def debug_eval(str, binding)
|
378
394
|
begin
|
379
|
-
|
395
|
+
val = eval(str, binding)
|
380
396
|
rescue StandardError, ScriptError => e
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
397
|
+
at = eval("caller(1)", binding)
|
398
|
+
stdout.printf "%s:%s\n", at.shift, e.to_s.sub(/\(eval\):1:(in `.*?':)?/, '')
|
399
|
+
for i in at
|
400
|
+
stdout.printf "\tfrom %s\n", i
|
401
|
+
end
|
402
|
+
throw :debug_error
|
387
403
|
end
|
388
404
|
end
|
389
405
|
|
390
406
|
def debug_silent_eval(str, binding)
|
391
407
|
begin
|
392
|
-
|
408
|
+
eval(str, binding)
|
393
409
|
rescue StandardError, ScriptError
|
394
|
-
|
410
|
+
nil
|
395
411
|
end
|
396
412
|
end
|
397
413
|
|
398
414
|
def debug_variable_info(input, binding)
|
399
415
|
case input
|
400
416
|
when /^\s*g(?:lobal)?\s*$/
|
401
|
-
|
417
|
+
var_list(global_variables, binding)
|
402
418
|
|
403
419
|
when /^\s*l(?:ocal)?\s*$/
|
404
|
-
|
420
|
+
var_list(eval("local_variables", binding), binding)
|
405
421
|
|
406
422
|
when /^\s*i(?:nstance)?\s+/
|
407
|
-
|
408
|
-
|
423
|
+
obj = debug_eval($', binding)
|
424
|
+
var_list(obj.instance_variables, obj.instance_eval{binding()})
|
409
425
|
|
410
426
|
when /^\s*c(?:onst(?:ant)?)?\s+/
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
427
|
+
obj = debug_eval($', binding)
|
428
|
+
unless obj.kind_of? Module
|
429
|
+
stdout.print "Should be Class/Module: ", $', "\n"
|
430
|
+
else
|
431
|
+
var_list(obj.constants, obj.module_eval{binding()})
|
432
|
+
end
|
417
433
|
end
|
418
434
|
end
|
419
435
|
|
420
436
|
def display_frames(pos)
|
421
437
|
self.frames.each_with_index do |frame, idx|
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
438
|
+
if idx == pos
|
439
|
+
stdout.print "--> "
|
440
|
+
else
|
441
|
+
stdout.print " "
|
442
|
+
end
|
443
|
+
stdout.print format_frame(frame, idx)
|
428
444
|
end
|
429
445
|
end
|
430
446
|
|
431
447
|
def format_frame(frame, pos)
|
432
448
|
bind, file, line, id = frame.binding, frame.file, frame.line, frame.id
|
433
449
|
sprintf "#%d %s:%s%s\n", pos + 1, file, line,
|
434
|
-
|
450
|
+
(id ? ":in `#{id.id2name}'" : "")
|
435
451
|
end
|
436
452
|
|
437
453
|
def var_list(ary, binding)
|
438
454
|
ary.sort!
|
439
455
|
for v in ary
|
440
|
-
|
456
|
+
stdout.printf " %s => %s\n", v, eval(v, binding).inspect
|
441
457
|
end
|
442
458
|
end
|
443
459
|
|
444
460
|
def display_list(b, e, file, line)
|
445
461
|
stdout.printf "[%d, %d] in %s\n", b, e, file
|
446
462
|
if lines = SCRIPT_LINES__[file] and lines != true
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
463
|
+
n = 0
|
464
|
+
b.upto(e) do |n|
|
465
|
+
if n > 0 && lines[n-1]
|
466
|
+
if n == line
|
467
|
+
stdout.printf "=> %d %s\n", n, lines[n-1].chomp
|
468
|
+
else
|
469
|
+
stdout.printf " %d %s\n", n, lines[n-1].chomp
|
470
|
+
end
|
471
|
+
end
|
472
|
+
end
|
457
473
|
else
|
458
|
-
|
474
|
+
stdout.printf "No sourcefile available for %s\n", file
|
459
475
|
end
|
460
476
|
end
|
461
477
|
|
462
478
|
def line_at(file, line)
|
463
479
|
lines = SCRIPT_LINES__[file]
|
464
480
|
if lines
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
481
|
+
return "\n" if lines == true
|
482
|
+
line = lines[line-1]
|
483
|
+
return "\n" unless line
|
484
|
+
return line.gsub(/^\s+/, '')
|
469
485
|
end
|
470
486
|
return "\n"
|
471
487
|
end
|
@@ -499,56 +515,56 @@ EOHELP
|
|
499
515
|
def debug_method_info(input, binding)
|
500
516
|
case input
|
501
517
|
when /^i(:?nstance)?\s+/
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
518
|
+
obj = debug_eval($', binding)
|
519
|
+
|
520
|
+
len = 0
|
521
|
+
for v in obj.methods.sort
|
522
|
+
len += v.size + 1
|
523
|
+
if len > 70
|
524
|
+
len = v.size + 1
|
525
|
+
stdout.print "\n"
|
526
|
+
end
|
527
|
+
stdout.print v, " "
|
528
|
+
end
|
529
|
+
stdout.print "\n"
|
514
530
|
|
515
531
|
else
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
532
|
+
obj = debug_eval(input, binding)
|
533
|
+
unless obj.kind_of? Module
|
534
|
+
stdout.print "Should be Class/Module: ", input, "\n"
|
535
|
+
else
|
536
|
+
len = 0
|
537
|
+
for v in obj.instance_methods(false).sort
|
538
|
+
len += v.size + 1
|
539
|
+
if len > 70
|
540
|
+
len = v.size + 1
|
541
|
+
stdout.print "\n"
|
542
|
+
end
|
543
|
+
stdout.print v, " "
|
544
|
+
end
|
545
|
+
stdout.print "\n"
|
546
|
+
end
|
531
547
|
end
|
532
548
|
end
|
533
549
|
|
534
550
|
def display_context(c)
|
535
551
|
if c.thread == Thread.current
|
536
|
-
|
552
|
+
stdout.print "+"
|
537
553
|
else
|
538
|
-
|
554
|
+
stdout.print " "
|
539
555
|
end
|
540
556
|
stdout.printf "%d ", c.thnum
|
541
557
|
stdout.print c.thread.inspect, "\t"
|
542
558
|
last_frame = c.frames.first
|
543
559
|
if last_frame
|
544
|
-
|
560
|
+
@stdout.print last_frame.file,":",last_frame.line
|
545
561
|
end
|
546
562
|
@stdout.print "\n"
|
547
563
|
end
|
548
564
|
|
549
565
|
def display_all_contexts
|
550
566
|
threads = contexts.sort_by{|c| c.thnum}.each do |c|
|
551
|
-
|
567
|
+
display_context(c)
|
552
568
|
end
|
553
569
|
end
|
554
570
|
|
@@ -559,43 +575,43 @@ EOHELP
|
|
559
575
|
def debug_thread_info(input)
|
560
576
|
case input
|
561
577
|
when /^l(?:ist)?/
|
562
|
-
|
578
|
+
display_all_contexts
|
563
579
|
|
564
580
|
when /^c(?:ur(?:rent)?)?$/
|
565
|
-
|
581
|
+
display_context(current_context)
|
566
582
|
|
567
583
|
when /^(?:sw(?:itch)?\s+)?(\d+)/
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
584
|
+
c = get_context($1.to_i)
|
585
|
+
if c == current_context
|
586
|
+
stdout.print "It's the current thread.\n"
|
587
|
+
else
|
588
|
+
display_context(c)
|
589
|
+
c.stop_next = 1
|
590
|
+
c.thread.run
|
591
|
+
return :cont
|
592
|
+
end
|
577
593
|
|
578
594
|
when /^stop\s+(\d+)/
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
595
|
+
c = get_context($1.to_i)
|
596
|
+
if c == current_context
|
597
|
+
stdout.print "It's the current thread.\n"
|
598
|
+
elsif c.thread.stop?
|
599
|
+
stdout.print "Already stopped.\n"
|
600
|
+
else
|
601
|
+
display_context(c)
|
602
|
+
c.set_suspend
|
603
|
+
end
|
588
604
|
|
589
605
|
when /^resume\s+(\d+)/
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
606
|
+
c = get_context($1.to_i)
|
607
|
+
if c == current_context
|
608
|
+
stdout.print "It's the current thread.\n"
|
609
|
+
elsif !c.thread.stop?
|
610
|
+
stdout.print "Already running."
|
611
|
+
else
|
612
|
+
display_context(c)
|
613
|
+
c.thread.run
|
614
|
+
end
|
599
615
|
end
|
600
616
|
end
|
601
617
|
end
|