debug 1.0.0.beta4 → 1.0.0.beta8
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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +34 -0
- data/.gitignore +1 -0
- data/CONTRIBUTING.md +239 -0
- data/Gemfile +2 -1
- data/README.md +424 -215
- data/Rakefile +2 -1
- data/TODO.md +0 -6
- data/bin/gentest +22 -0
- data/debug.gemspec +2 -0
- data/exe/rdbg +14 -11
- data/ext/debug/debug.c +9 -8
- data/lib/debug.rb +3 -0
- data/lib/debug/breakpoint.rb +101 -43
- data/lib/debug/client.rb +55 -13
- data/lib/debug/color.rb +76 -0
- data/lib/debug/config.rb +130 -39
- data/lib/debug/console.rb +24 -3
- data/lib/debug/frame_info.rb +63 -31
- data/lib/debug/open.rb +4 -1
- data/lib/debug/open_nonstop.rb +15 -0
- data/lib/debug/server.rb +90 -32
- data/lib/debug/server_dap.rb +607 -0
- data/lib/debug/session.rb +461 -174
- data/lib/debug/source_repository.rb +55 -33
- data/lib/debug/start.rb +5 -0
- data/lib/debug/thread_client.rb +176 -59
- data/lib/debug/version.rb +3 -1
- data/misc/README.md.erb +351 -204
- metadata +23 -4
- data/lib/debug/run.rb +0 -2
|
@@ -1,55 +1,77 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'color'
|
|
2
4
|
|
|
3
5
|
module DEBUGGER__
|
|
4
6
|
class SourceRepository
|
|
7
|
+
SrcInfo = Struct.new(:src, :colored)
|
|
8
|
+
|
|
5
9
|
def initialize
|
|
6
|
-
@files = {} # filename =>
|
|
7
|
-
@color_files = {}
|
|
10
|
+
@files = {} # filename => SrcInfo
|
|
8
11
|
end
|
|
9
12
|
|
|
10
13
|
def add iseq, src
|
|
11
|
-
path = iseq.absolute_path
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
if (path = iseq.absolute_path) && File.exist?(path)
|
|
15
|
+
add_path path
|
|
16
|
+
elsif src
|
|
17
|
+
add_iseq iseq, src
|
|
18
|
+
end
|
|
14
19
|
end
|
|
15
20
|
|
|
16
|
-
def
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
end
|
|
29
|
-
else
|
|
30
|
-
src = nil
|
|
21
|
+
def all_iseq iseq, rs = []
|
|
22
|
+
rs << iseq
|
|
23
|
+
iseq.each_child{|ci|
|
|
24
|
+
all_iseq(ci, rs)
|
|
25
|
+
}
|
|
26
|
+
rs
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private def add_iseq iseq, src
|
|
30
|
+
line = iseq.first_line
|
|
31
|
+
if line > 1
|
|
32
|
+
src = ("\n" * (line - 1)) + src
|
|
31
33
|
end
|
|
34
|
+
si = SrcInfo.new(src.lines)
|
|
32
35
|
|
|
33
|
-
|
|
36
|
+
all_iseq(iseq).each{|e|
|
|
37
|
+
e.instance_variable_set(:@debugger_si, si)
|
|
38
|
+
e.freeze
|
|
39
|
+
}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private def add_path path
|
|
43
|
+
begin
|
|
44
|
+
src = File.read(path)
|
|
34
45
|
src = src.gsub("\r\n", "\n") # CRLF -> LF
|
|
35
|
-
@files[path] = src.lines
|
|
46
|
+
@files[path] = SrcInfo.new(src.lines)
|
|
47
|
+
rescue SystemCallError
|
|
36
48
|
end
|
|
37
49
|
end
|
|
38
50
|
|
|
39
|
-
def
|
|
40
|
-
|
|
51
|
+
private def get_si iseq
|
|
52
|
+
return unless iseq
|
|
53
|
+
|
|
54
|
+
if iseq.instance_variable_defined?(:@debugger_si)
|
|
55
|
+
iseq.instance_variable_get(:@debugger_si)
|
|
56
|
+
elsif @files.has_key?(path = iseq.absolute_path)
|
|
41
57
|
@files[path]
|
|
42
|
-
|
|
43
|
-
add_path
|
|
58
|
+
elsif path
|
|
59
|
+
add_path(path)
|
|
44
60
|
end
|
|
45
61
|
end
|
|
46
62
|
|
|
47
|
-
def
|
|
48
|
-
if
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
63
|
+
def get iseq
|
|
64
|
+
if si = get_si(iseq)
|
|
65
|
+
si.src
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
include Color
|
|
70
|
+
|
|
71
|
+
def get_colored iseq
|
|
72
|
+
if si = get_si(iseq)
|
|
73
|
+
si.colored || begin
|
|
74
|
+
si.colored = colorize_code(si.src.join).lines
|
|
53
75
|
end
|
|
54
76
|
end
|
|
55
77
|
end
|
data/lib/debug/start.rb
ADDED
data/lib/debug/thread_client.rb
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'objspace'
|
|
2
4
|
require 'pp'
|
|
3
|
-
|
|
5
|
+
|
|
4
6
|
require_relative 'frame_info'
|
|
7
|
+
require_relative 'color'
|
|
5
8
|
|
|
6
9
|
module DEBUGGER__
|
|
7
10
|
class ThreadClient
|
|
@@ -12,23 +15,46 @@ module DEBUGGER__
|
|
|
12
15
|
end
|
|
13
16
|
end
|
|
14
17
|
|
|
18
|
+
include Color
|
|
19
|
+
|
|
15
20
|
attr_reader :location, :thread, :mode, :id
|
|
16
21
|
|
|
17
|
-
def
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
str
|
|
22
|
-
end
|
|
22
|
+
def assemble_arguments(args)
|
|
23
|
+
args.map do |arg|
|
|
24
|
+
"#{colorize_cyan(arg[:name])}=#{arg[:value]}"
|
|
25
|
+
end.join(", ")
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
def default_frame_formatter frame
|
|
26
|
-
call_identifier_str =
|
|
27
|
-
|
|
29
|
+
call_identifier_str =
|
|
30
|
+
case frame.frame_type
|
|
31
|
+
when :block
|
|
32
|
+
level, block_loc, args = frame.block_identifier
|
|
33
|
+
|
|
34
|
+
if !args.empty?
|
|
35
|
+
args_str = " {|#{assemble_arguments(args)}|}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
"#{colorize_blue("block")}#{args_str} in #{colorize_blue(block_loc + level)}"
|
|
39
|
+
when :method
|
|
40
|
+
ci, args = frame.method_identifier
|
|
41
|
+
|
|
42
|
+
if !args.empty?
|
|
43
|
+
args_str = "(#{assemble_arguments(args)})"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
"#{colorize_blue(ci)}#{args_str}"
|
|
47
|
+
when :c
|
|
48
|
+
colorize_blue(frame.c_identifier)
|
|
49
|
+
when :other
|
|
50
|
+
colorize_blue(frame.other_identifier)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
location_str = colorize(frame.location_str, [:GREEN])
|
|
28
54
|
result = "#{call_identifier_str} at #{location_str}"
|
|
29
55
|
|
|
30
56
|
if return_str = frame.return_str
|
|
31
|
-
return_str = colorize(frame.return_str, [:MAGENTA])
|
|
57
|
+
return_str = colorize(frame.return_str, [:MAGENTA, :BOLD])
|
|
32
58
|
result += " #=> #{return_str}"
|
|
33
59
|
end
|
|
34
60
|
|
|
@@ -38,14 +64,20 @@ module DEBUGGER__
|
|
|
38
64
|
def initialize id, q_evt, q_cmd, thr = Thread.current
|
|
39
65
|
@id = id
|
|
40
66
|
@thread = thr
|
|
67
|
+
@target_frames = nil
|
|
41
68
|
@q_evt = q_evt
|
|
42
69
|
@q_cmd = q_cmd
|
|
43
70
|
@step_tp = nil
|
|
44
71
|
@output = []
|
|
45
|
-
@src_lines_on_stop = (::DEBUGGER__::CONFIG[:show_src_lines] || 10).to_i
|
|
46
|
-
@show_frames_on_stop = (::DEBUGGER__::CONFIG[:show_frames] || 2).to_i
|
|
47
72
|
@frame_formatter = method(:default_frame_formatter)
|
|
73
|
+
@var_map = {} # { thread_local_var_id => obj } for DAP
|
|
48
74
|
set_mode nil
|
|
75
|
+
|
|
76
|
+
::DEBUGGER__.info("Thread \##{@id} is created.")
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def name
|
|
80
|
+
"##{@id} #{@thread.name || @thread.backtrace.last}"
|
|
49
81
|
end
|
|
50
82
|
|
|
51
83
|
def close
|
|
@@ -71,8 +103,14 @@ module DEBUGGER__
|
|
|
71
103
|
@q_cmd << req
|
|
72
104
|
end
|
|
73
105
|
|
|
106
|
+
def generate_info
|
|
107
|
+
return unless current_frame
|
|
108
|
+
|
|
109
|
+
{ location: current_frame.location_str, line: current_frame.location.lineno }
|
|
110
|
+
end
|
|
111
|
+
|
|
74
112
|
def event! ev, *args
|
|
75
|
-
@q_evt << [self, @output, ev, *args]
|
|
113
|
+
@q_evt << [self, @output, ev, generate_info, *args]
|
|
76
114
|
@output = []
|
|
77
115
|
end
|
|
78
116
|
|
|
@@ -100,6 +138,11 @@ module DEBUGGER__
|
|
|
100
138
|
wait_next_action
|
|
101
139
|
end
|
|
102
140
|
|
|
141
|
+
def on_init name
|
|
142
|
+
event! :init, name
|
|
143
|
+
wait_next_action
|
|
144
|
+
end
|
|
145
|
+
|
|
103
146
|
def on_breakpoint tp, bp
|
|
104
147
|
on_suspend tp.event, tp, bp: bp
|
|
105
148
|
end
|
|
@@ -116,11 +159,16 @@ module DEBUGGER__
|
|
|
116
159
|
cf.has_return_value = true
|
|
117
160
|
cf.return_value = tp.return_value
|
|
118
161
|
end
|
|
162
|
+
|
|
163
|
+
if CatchBreakpoint === bp
|
|
164
|
+
cf.has_raised_exception = true
|
|
165
|
+
cf.raised_exception = bp.last_exc
|
|
166
|
+
end
|
|
119
167
|
end
|
|
120
168
|
|
|
121
169
|
if event != :pause
|
|
122
|
-
show_src max_lines:
|
|
123
|
-
show_frames
|
|
170
|
+
show_src max_lines: (::DEBUGGER__::CONFIG[:show_src_lines] || 10)
|
|
171
|
+
show_frames ::DEBUGGER__::CONFIG[:show_frames] || 2
|
|
124
172
|
|
|
125
173
|
if bp
|
|
126
174
|
event! :suspend, :breakpoint, bp.key
|
|
@@ -187,7 +235,6 @@ module DEBUGGER__
|
|
|
187
235
|
start_line: nil,
|
|
188
236
|
end_line: nil,
|
|
189
237
|
dir: +1)
|
|
190
|
-
|
|
191
238
|
if @target_frames && frame = @target_frames[frame_index]
|
|
192
239
|
if file_lines = frame.file_lines
|
|
193
240
|
frame_line = frame.location.lineno - 1
|
|
@@ -229,6 +276,10 @@ module DEBUGGER__
|
|
|
229
276
|
puts "# No sourcefile available for #{frame.path}"
|
|
230
277
|
end
|
|
231
278
|
end
|
|
279
|
+
rescue Exception => e
|
|
280
|
+
p e
|
|
281
|
+
pp e.backtrace
|
|
282
|
+
exit!
|
|
232
283
|
end
|
|
233
284
|
|
|
234
285
|
def show_by_editor path = nil
|
|
@@ -253,16 +304,39 @@ module DEBUGGER__
|
|
|
253
304
|
end
|
|
254
305
|
end
|
|
255
306
|
|
|
307
|
+
def puts_variable_info label, obj
|
|
308
|
+
info = "#{colorize_cyan(label)} => #{colored_inspect(obj)}".lines
|
|
309
|
+
w = SESSION.width
|
|
310
|
+
max_inspect_lines = CONFIG[:show_inspect_lines] || 10
|
|
311
|
+
|
|
312
|
+
if (max_inspect_lines > 0 && (info.size > max_inspect_lines)) || info.any?{|l| l.size > w}
|
|
313
|
+
info = "#{colorize_cyan(label)} => #{colored_inspect(obj, no_color: true)}".lines
|
|
314
|
+
if max_inspect_lines > 0 && info.size > max_inspect_lines
|
|
315
|
+
info = info.first(max_inspect_lines - 2) +
|
|
316
|
+
["...(#{info.size - (max_inspect_lines - 1)} lines)\n" + info.last]
|
|
317
|
+
end
|
|
318
|
+
info.map!{|l|
|
|
319
|
+
l.length > w ? l[0..(w-4)] + '...' : l
|
|
320
|
+
}
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
puts info
|
|
324
|
+
end
|
|
325
|
+
|
|
256
326
|
def show_locals
|
|
257
327
|
if s = current_frame&.self
|
|
258
|
-
|
|
328
|
+
puts_variable_info '%self', s
|
|
259
329
|
end
|
|
260
330
|
if current_frame&.has_return_value
|
|
261
|
-
|
|
331
|
+
puts_variable_info '%return', current_frame.return_value
|
|
332
|
+
end
|
|
333
|
+
if current_frame&.has_raised_exception
|
|
334
|
+
puts_variable_info "%raised", current_frame.raised_exception
|
|
262
335
|
end
|
|
263
336
|
if b = current_frame&.binding
|
|
264
337
|
b.local_variables.each{|loc|
|
|
265
|
-
|
|
338
|
+
value = b.local_variable_get(loc)
|
|
339
|
+
puts_variable_info loc, value
|
|
266
340
|
}
|
|
267
341
|
end
|
|
268
342
|
end
|
|
@@ -270,22 +344,27 @@ module DEBUGGER__
|
|
|
270
344
|
def show_ivars
|
|
271
345
|
if s = current_frame&.self
|
|
272
346
|
s.instance_variables.each{|iv|
|
|
273
|
-
|
|
347
|
+
value = s.instance_variable_get(iv)
|
|
348
|
+
puts_variable_info iv, value
|
|
274
349
|
}
|
|
275
350
|
end
|
|
276
351
|
end
|
|
277
352
|
|
|
353
|
+
def instance_eval_for_cmethod frame_self, src
|
|
354
|
+
frame_self.instance_eval(src)
|
|
355
|
+
end
|
|
356
|
+
|
|
278
357
|
def frame_eval src, re_raise: false
|
|
279
358
|
begin
|
|
280
359
|
@success_last_eval = false
|
|
281
360
|
|
|
282
361
|
b = current_frame.binding
|
|
283
362
|
result = if b
|
|
284
|
-
f,
|
|
363
|
+
f, _l = b.source_location
|
|
285
364
|
b.eval(src, "(rdbg)/#{f}")
|
|
286
365
|
else
|
|
287
366
|
frame_self = current_frame.self
|
|
288
|
-
frame_self
|
|
367
|
+
instance_eval_for_cmethod(frame_self, src)
|
|
289
368
|
end
|
|
290
369
|
@success_last_eval = true
|
|
291
370
|
result
|
|
@@ -303,21 +382,35 @@ module DEBUGGER__
|
|
|
303
382
|
end
|
|
304
383
|
end
|
|
305
384
|
|
|
306
|
-
def frame_str(i)
|
|
385
|
+
def frame_str(i, frame: @target_frames[i])
|
|
307
386
|
cur_str = (@current_frame_index == i ? '=>' : ' ')
|
|
308
387
|
prefix = "#{cur_str}##{i}"
|
|
309
|
-
frame = @target_frames[i]
|
|
310
388
|
frame_string = @frame_formatter.call(frame)
|
|
311
389
|
"#{prefix}\t#{frame_string}"
|
|
312
390
|
end
|
|
313
391
|
|
|
314
|
-
def show_frames max =
|
|
315
|
-
if
|
|
316
|
-
|
|
317
|
-
|
|
392
|
+
def show_frames max = nil, pattern = nil
|
|
393
|
+
if @target_frames && (max ||= @target_frames.size) > 0
|
|
394
|
+
frames = []
|
|
395
|
+
@target_frames.each_with_index{|f, i|
|
|
396
|
+
next if pattern && !(f.name.match?(pattern) || f.location_str.match?(pattern))
|
|
397
|
+
next if CONFIG[:skip_path] && CONFIG[:skip_path].any?{|pat|
|
|
398
|
+
case pat
|
|
399
|
+
when String
|
|
400
|
+
f.location_str.start_with?(pat)
|
|
401
|
+
when Regexp
|
|
402
|
+
f.location_str.match?(pat)
|
|
403
|
+
end
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
frames << [i, f]
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
size = frames.size
|
|
318
410
|
max.times{|i|
|
|
319
|
-
break
|
|
320
|
-
|
|
411
|
+
break unless frames[i]
|
|
412
|
+
index, frame = frames[i]
|
|
413
|
+
puts frame_str(index, frame: frame)
|
|
321
414
|
}
|
|
322
415
|
puts " # and #{size - max} frames (use `bt' command for all frames)" if max < size
|
|
323
416
|
end
|
|
@@ -345,18 +438,22 @@ module DEBUGGER__
|
|
|
345
438
|
end
|
|
346
439
|
end
|
|
347
440
|
|
|
348
|
-
def
|
|
441
|
+
def make_breakpoint args
|
|
349
442
|
case args.first
|
|
350
443
|
when :method
|
|
351
|
-
klass_name, op, method_name, cond = args[1..]
|
|
352
|
-
bp = MethodBreakpoint.new(current_frame.binding, klass_name, op, method_name, cond)
|
|
444
|
+
klass_name, op, method_name, cond, cmd = args[1..]
|
|
445
|
+
bp = MethodBreakpoint.new(current_frame.binding, klass_name, op, method_name, cond, command: cmd)
|
|
353
446
|
begin
|
|
354
447
|
bp.enable
|
|
355
448
|
rescue Exception => e
|
|
356
449
|
puts e.message
|
|
357
450
|
::DEBUGGER__::METHOD_ADDED_TRACKER.enable
|
|
358
451
|
end
|
|
359
|
-
|
|
452
|
+
|
|
453
|
+
bp
|
|
454
|
+
when :watch
|
|
455
|
+
ivar, object, result = args[1..]
|
|
456
|
+
WatchIVarBreakpoint.new(ivar, object, result)
|
|
360
457
|
else
|
|
361
458
|
raise "unknown breakpoint: #{args}"
|
|
362
459
|
end
|
|
@@ -369,6 +466,8 @@ module DEBUGGER__
|
|
|
369
466
|
def wait_next_action
|
|
370
467
|
set_mode :wait_next_action
|
|
371
468
|
|
|
469
|
+
SESSION.check_forked
|
|
470
|
+
|
|
372
471
|
while cmds = @q_cmd.pop
|
|
373
472
|
# pp [self, cmds: cmds]
|
|
374
473
|
|
|
@@ -386,20 +485,28 @@ module DEBUGGER__
|
|
|
386
485
|
frame = @target_frames.first
|
|
387
486
|
path = frame.location.absolute_path || "!eval:#{frame.path}"
|
|
388
487
|
line = frame.location.lineno
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
next_line =
|
|
488
|
+
|
|
489
|
+
if frame.iseq
|
|
490
|
+
frame.iseq.traceable_lines_norec(lines = {})
|
|
491
|
+
next_line = lines.keys.bsearch{|e| e > line}
|
|
492
|
+
if !next_line && (last_line = frame.iseq.last_line) > line
|
|
493
|
+
next_line = last_line
|
|
494
|
+
end
|
|
393
495
|
end
|
|
496
|
+
|
|
394
497
|
depth = @target_frames.first.frame_depth
|
|
395
498
|
|
|
396
499
|
step_tp{
|
|
397
500
|
loc = caller_locations(2, 1).first
|
|
398
501
|
loc_path = loc.absolute_path || "!eval:#{loc.path}"
|
|
399
502
|
|
|
503
|
+
# same stack depth
|
|
504
|
+
(DEBUGGER__.frame_depth - 3 <= depth) ||
|
|
505
|
+
|
|
506
|
+
# different frame
|
|
400
507
|
(next_line && loc_path == path &&
|
|
401
|
-
|
|
402
|
-
|
|
508
|
+
(loc_lineno = loc.lineno) > line &&
|
|
509
|
+
loc_lineno <= next_line)
|
|
403
510
|
}
|
|
404
511
|
when :finish
|
|
405
512
|
depth = @target_frames.first.frame_depth
|
|
@@ -414,20 +521,16 @@ module DEBUGGER__
|
|
|
414
521
|
when :eval
|
|
415
522
|
eval_type, eval_src = *args
|
|
416
523
|
|
|
417
|
-
case eval_type
|
|
418
|
-
when :display, :try_display
|
|
419
|
-
else
|
|
420
|
-
result = frame_eval(eval_src)
|
|
421
|
-
end
|
|
422
524
|
result_type = nil
|
|
423
525
|
|
|
424
526
|
case eval_type
|
|
425
527
|
when :p
|
|
528
|
+
result = frame_eval(eval_src)
|
|
426
529
|
puts "=> " + result.inspect
|
|
427
530
|
when :pp
|
|
531
|
+
result = frame_eval(eval_src)
|
|
428
532
|
puts "=> "
|
|
429
|
-
|
|
430
|
-
puts out
|
|
533
|
+
puts color_pp(result, SESSION.width)
|
|
431
534
|
when :call
|
|
432
535
|
result = frame_eval(eval_src)
|
|
433
536
|
when :display, :try_display
|
|
@@ -442,14 +545,6 @@ module DEBUGGER__
|
|
|
442
545
|
|
|
443
546
|
result_type = eval_type
|
|
444
547
|
result = failed_results
|
|
445
|
-
when :watch
|
|
446
|
-
if @success_last_eval
|
|
447
|
-
puts "#{eval_src} = #{result}"
|
|
448
|
-
result = WatchExprBreakpoint.new(eval_src, result)
|
|
449
|
-
result_type = :watch
|
|
450
|
-
else
|
|
451
|
-
result = nil
|
|
452
|
-
end
|
|
453
548
|
else
|
|
454
549
|
raise "unknown error option: #{args.inspect}"
|
|
455
550
|
end
|
|
@@ -490,7 +585,8 @@ module DEBUGGER__
|
|
|
490
585
|
|
|
491
586
|
case type
|
|
492
587
|
when :backtrace
|
|
493
|
-
|
|
588
|
+
max_lines, pattern = *args
|
|
589
|
+
show_frames max_lines, pattern
|
|
494
590
|
|
|
495
591
|
when :list
|
|
496
592
|
show_src(update_line: true, **(args.first || {}))
|
|
@@ -512,9 +608,30 @@ module DEBUGGER__
|
|
|
512
608
|
end
|
|
513
609
|
|
|
514
610
|
event! :result, nil
|
|
515
|
-
|
|
516
611
|
when :breakpoint
|
|
517
|
-
|
|
612
|
+
case args[0]
|
|
613
|
+
when :method
|
|
614
|
+
bp = make_breakpoint args
|
|
615
|
+
event! :result, :method_breakpoint, bp
|
|
616
|
+
when :watch
|
|
617
|
+
ivar = args[1]
|
|
618
|
+
result = frame_eval(ivar)
|
|
619
|
+
|
|
620
|
+
if @success_last_eval
|
|
621
|
+
object =
|
|
622
|
+
if b = current_frame.binding
|
|
623
|
+
b.receiver
|
|
624
|
+
else
|
|
625
|
+
current_frame.self
|
|
626
|
+
end
|
|
627
|
+
bp = make_breakpoint [:watch, ivar, object, result]
|
|
628
|
+
event! :result, :watch_breakpoint, bp
|
|
629
|
+
else
|
|
630
|
+
event! :result, nil
|
|
631
|
+
end
|
|
632
|
+
end
|
|
633
|
+
when :dap
|
|
634
|
+
process_dap args
|
|
518
635
|
else
|
|
519
636
|
raise [cmd, *args].inspect
|
|
520
637
|
end
|
|
@@ -523,7 +640,7 @@ module DEBUGGER__
|
|
|
523
640
|
rescue SystemExit
|
|
524
641
|
raise
|
|
525
642
|
rescue Exception => e
|
|
526
|
-
pp [__FILE__
|
|
643
|
+
pp ["DEBUGGER Exception: #{__FILE__}:#{__LINE__}", e, e.backtrace]
|
|
527
644
|
raise
|
|
528
645
|
ensure
|
|
529
646
|
set_mode nil
|