debug 1.3.3 → 1.5.0
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/CONTRIBUTING.md +163 -6
- data/Gemfile +1 -0
- data/README.md +42 -15
- data/Rakefile +5 -5
- data/debug.gemspec +6 -4
- data/ext/debug/debug.c +88 -1
- data/ext/debug/extconf.rb +11 -0
- data/lib/debug/breakpoint.rb +75 -36
- data/lib/debug/client.rb +65 -18
- data/lib/debug/color.rb +29 -19
- data/lib/debug/config.rb +6 -3
- data/lib/debug/console.rb +50 -15
- data/lib/debug/frame_info.rb +14 -20
- data/lib/debug/local.rb +1 -1
- data/lib/debug/prelude.rb +2 -2
- data/lib/debug/server.rb +100 -94
- data/lib/debug/server_cdp.rb +878 -160
- data/lib/debug/server_dap.rb +277 -81
- data/lib/debug/session.rb +327 -154
- data/lib/debug/source_repository.rb +90 -52
- data/lib/debug/thread_client.rb +149 -78
- data/lib/debug/tracer.rb +4 -10
- data/lib/debug/version.rb +1 -1
- data/misc/README.md.erb +16 -8
- metadata +4 -12
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -24
- data/.github/ISSUE_TEMPLATE/custom.md +0 -10
- data/.github/ISSUE_TEMPLATE/feature_request.md +0 -14
- data/.github/workflows/ruby.yml +0 -34
- data/.gitignore +0 -12
- data/bin/console +0 -14
- data/bin/gentest +0 -22
- data/bin/setup +0 -8
@@ -4,74 +4,112 @@ require_relative 'color'
|
|
4
4
|
|
5
5
|
module DEBUGGER__
|
6
6
|
class SourceRepository
|
7
|
-
|
7
|
+
include Color
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
if RubyVM.respond_to? :keep_script_lines
|
10
|
+
# Ruby 3.1 and later
|
11
|
+
RubyVM.keep_script_lines = true
|
12
|
+
require 'objspace'
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
elsif src
|
17
|
-
add_iseq iseq, src
|
14
|
+
def initialize
|
15
|
+
# cache
|
16
|
+
@cmap = ObjectSpace::WeakMap.new
|
18
17
|
end
|
19
|
-
end
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
19
|
+
def add iseq, src
|
20
|
+
# do nothing
|
21
|
+
end
|
22
|
+
|
23
|
+
def get iseq
|
24
|
+
return unless iseq
|
28
25
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
if lines = iseq.script_lines&.map(&:chomp)
|
27
|
+
lines
|
28
|
+
else
|
29
|
+
if (path = (iseq.absolute_path || iseq.path)) && File.exist?(path)
|
30
|
+
File.readlines(path, chomp: true)
|
31
|
+
else
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
end
|
33
35
|
end
|
34
|
-
si = SrcInfo.new(src.lines)
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
def get_colored iseq
|
38
|
+
if lines = @cmap[iseq]
|
39
|
+
lines
|
40
|
+
else
|
41
|
+
if src_lines = get(iseq)
|
42
|
+
@cmap[iseq] = colorize_code(src_lines.join("\n")).lines
|
43
|
+
else
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
else
|
49
|
+
# ruby 3.0 or earlier
|
50
|
+
SrcInfo = Struct.new(:src, :colored)
|
41
51
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
52
|
+
def initialize
|
53
|
+
@files = {} # filename => SrcInfo
|
54
|
+
end
|
55
|
+
|
56
|
+
def add iseq, src
|
57
|
+
if (path = (iseq.absolute_path || iseq.path)) && File.exist?(path)
|
58
|
+
add_path path
|
59
|
+
elsif src
|
60
|
+
add_iseq iseq, src
|
61
|
+
end
|
48
62
|
end
|
49
|
-
end
|
50
63
|
|
51
|
-
|
52
|
-
|
64
|
+
private def all_iseq iseq, rs = []
|
65
|
+
rs << iseq
|
66
|
+
iseq.each_child{|ci|
|
67
|
+
all_iseq(ci, rs)
|
68
|
+
}
|
69
|
+
rs
|
70
|
+
end
|
53
71
|
|
54
|
-
|
55
|
-
iseq.
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
72
|
+
private def add_iseq iseq, src
|
73
|
+
line = iseq.first_line
|
74
|
+
if line > 1
|
75
|
+
src = ("\n" * (line - 1)) + src
|
76
|
+
end
|
77
|
+
si = SrcInfo.new(src.lines)
|
78
|
+
all_iseq(iseq).each{|e|
|
79
|
+
e.instance_variable_set(:@debugger_si, si)
|
80
|
+
e.freeze
|
81
|
+
}
|
60
82
|
end
|
61
|
-
end
|
62
83
|
|
63
|
-
|
64
|
-
|
65
|
-
|
84
|
+
private def add_path path
|
85
|
+
src_lines = File.readlines(path, chomp: true)
|
86
|
+
@files[path] = SrcInfo.new(src_lines)
|
87
|
+
rescue SystemCallError
|
66
88
|
end
|
67
|
-
end
|
68
89
|
|
69
|
-
|
90
|
+
private def get_si iseq
|
91
|
+
return unless iseq
|
92
|
+
|
93
|
+
if iseq.instance_variable_defined?(:@debugger_si)
|
94
|
+
iseq.instance_variable_get(:@debugger_si)
|
95
|
+
elsif @files.has_key?(path = (iseq.absolute_path || iseq.path))
|
96
|
+
@files[path]
|
97
|
+
elsif path
|
98
|
+
add_path(path)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def get iseq
|
103
|
+
if si = get_si(iseq)
|
104
|
+
si.src
|
105
|
+
end
|
106
|
+
end
|
70
107
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
108
|
+
def get_colored iseq
|
109
|
+
if si = get_si(iseq)
|
110
|
+
si.colored || begin
|
111
|
+
si.colored = colorize_code(si.src.join("\n")).lines
|
112
|
+
end
|
75
113
|
end
|
76
114
|
end
|
77
115
|
end
|
data/lib/debug/thread_client.rb
CHANGED
@@ -8,7 +8,11 @@ require_relative 'color'
|
|
8
8
|
module DEBUGGER__
|
9
9
|
module SkipPathHelper
|
10
10
|
def skip_path?(path)
|
11
|
-
(skip_paths = CONFIG[:skip_path]) && skip_paths.any?{|skip_path| path.match?(skip_path)}
|
11
|
+
!path || skip_internal_path?(path) || (skip_paths = CONFIG[:skip_path]) && skip_paths.any?{|skip_path| path.match?(skip_path)}
|
12
|
+
end
|
13
|
+
|
14
|
+
def skip_internal_path?(path)
|
15
|
+
path.start_with?(__dir__) || path.start_with?('<internal:')
|
12
16
|
end
|
13
17
|
|
14
18
|
def skip_location?(loc)
|
@@ -22,7 +26,7 @@ module DEBUGGER__
|
|
22
26
|
if thc = Thread.current[:DEBUGGER__ThreadClient]
|
23
27
|
thc
|
24
28
|
else
|
25
|
-
thc = SESSION.
|
29
|
+
thc = SESSION.get_thread_client
|
26
30
|
Thread.current[:DEBUGGER__ThreadClient] = thc
|
27
31
|
end
|
28
32
|
end
|
@@ -30,7 +34,11 @@ module DEBUGGER__
|
|
30
34
|
include Color
|
31
35
|
include SkipPathHelper
|
32
36
|
|
33
|
-
attr_reader :
|
37
|
+
attr_reader :thread, :id, :recorder
|
38
|
+
|
39
|
+
def location
|
40
|
+
current_frame&.location
|
41
|
+
end
|
34
42
|
|
35
43
|
def assemble_arguments(args)
|
36
44
|
args.map do |arg|
|
@@ -67,7 +75,7 @@ module DEBUGGER__
|
|
67
75
|
result = "#{call_identifier_str} at #{location_str}"
|
68
76
|
|
69
77
|
if return_str = frame.return_str
|
70
|
-
result += " #=> #{colorize_magenta(
|
78
|
+
result += " #=> #{colorize_magenta(return_str)}"
|
71
79
|
end
|
72
80
|
|
73
81
|
result
|
@@ -84,6 +92,7 @@ module DEBUGGER__
|
|
84
92
|
@output = []
|
85
93
|
@frame_formatter = method(:default_frame_formatter)
|
86
94
|
@var_map = {} # { thread_local_var_id => obj } for DAP
|
95
|
+
@obj_map = {} # { object_id => obj } for CDP
|
87
96
|
@recorder = nil
|
88
97
|
@mode = :waiting
|
89
98
|
set_mode :running
|
@@ -100,13 +109,13 @@ module DEBUGGER__
|
|
100
109
|
@is_management
|
101
110
|
end
|
102
111
|
|
103
|
-
def
|
112
|
+
def mark_as_management
|
104
113
|
@is_management = true
|
105
114
|
end
|
106
115
|
|
107
116
|
def set_mode mode
|
108
117
|
# STDERR.puts "#{@mode} => #{mode} @ #{caller.inspect}"
|
109
|
-
#pp caller
|
118
|
+
# pp caller
|
110
119
|
|
111
120
|
# mode transition check
|
112
121
|
case mode
|
@@ -148,14 +157,7 @@ module DEBUGGER__
|
|
148
157
|
end
|
149
158
|
|
150
159
|
def to_s
|
151
|
-
|
152
|
-
|
153
|
-
if loc
|
154
|
-
str = "(#{@thread.name || @thread.status})@#{loc}"
|
155
|
-
else
|
156
|
-
str = "(#{@thread.name || @thread.status})@#{@thread.to_s}"
|
157
|
-
end
|
158
|
-
|
160
|
+
str = "(#{@thread.name || @thread.status})@#{current_frame&.location || @thread.to_s}"
|
159
161
|
str += " (not under control)" unless self.waiting?
|
160
162
|
str
|
161
163
|
end
|
@@ -228,7 +230,7 @@ module DEBUGGER__
|
|
228
230
|
suspend :pause
|
229
231
|
end
|
230
232
|
|
231
|
-
def suspend event, tp = nil, bp: nil, sig: nil, postmortem_frames: nil, replay_frames: nil
|
233
|
+
def suspend event, tp = nil, bp: nil, sig: nil, postmortem_frames: nil, replay_frames: nil, postmortem_exc: nil
|
232
234
|
return if management?
|
233
235
|
|
234
236
|
@current_frame_index = 0
|
@@ -245,7 +247,6 @@ module DEBUGGER__
|
|
245
247
|
|
246
248
|
cf = @target_frames.first
|
247
249
|
if cf
|
248
|
-
@location = cf.location
|
249
250
|
case event
|
250
251
|
when :return, :b_return, :c_return
|
251
252
|
cf.has_return_value = true
|
@@ -256,10 +257,15 @@ module DEBUGGER__
|
|
256
257
|
cf.has_raised_exception = true
|
257
258
|
cf.raised_exception = bp.last_exc
|
258
259
|
end
|
260
|
+
|
261
|
+
if postmortem_exc
|
262
|
+
cf.has_raised_exception = true
|
263
|
+
cf.raised_exception = postmortem_exc
|
264
|
+
end
|
259
265
|
end
|
260
266
|
|
261
267
|
if event != :pause
|
262
|
-
show_src
|
268
|
+
show_src
|
263
269
|
show_frames CONFIG[:show_frames] || 2
|
264
270
|
|
265
271
|
set_mode :waiting
|
@@ -292,15 +298,15 @@ module DEBUGGER__
|
|
292
298
|
SUPPORT_TARGET_THREAD = false
|
293
299
|
end
|
294
300
|
|
295
|
-
def step_tp iter
|
301
|
+
def step_tp iter, events = [:line, :b_return, :return]
|
296
302
|
@step_tp.disable if @step_tp
|
297
303
|
|
298
304
|
thread = Thread.current
|
299
305
|
|
300
306
|
if SUPPORT_TARGET_THREAD
|
301
|
-
@step_tp = TracePoint.new(
|
307
|
+
@step_tp = TracePoint.new(*events){|tp|
|
302
308
|
next if SESSION.break_at? tp.path, tp.lineno
|
303
|
-
next if !yield
|
309
|
+
next if !yield(tp.event)
|
304
310
|
next if tp.path.start_with?(__dir__)
|
305
311
|
next if tp.path.start_with?('<internal:trace_point>')
|
306
312
|
next unless File.exist?(tp.path) if CONFIG[:skip_nosrc]
|
@@ -313,10 +319,10 @@ module DEBUGGER__
|
|
313
319
|
}
|
314
320
|
@step_tp.enable(target_thread: thread)
|
315
321
|
else
|
316
|
-
@step_tp = TracePoint.new(
|
322
|
+
@step_tp = TracePoint.new(*events){|tp|
|
317
323
|
next if thread != Thread.current
|
318
324
|
next if SESSION.break_at? tp.path, tp.lineno
|
319
|
-
next if !yield
|
325
|
+
next if !yield(tp.event)
|
320
326
|
next if tp.path.start_with?(__dir__)
|
321
327
|
next if tp.path.start_with?('<internal:trace_point>')
|
322
328
|
next unless File.exist?(tp.path) if CONFIG[:skip_nosrc]
|
@@ -333,43 +339,83 @@ module DEBUGGER__
|
|
333
339
|
|
334
340
|
## cmd helpers
|
335
341
|
|
336
|
-
|
337
|
-
|
338
|
-
|
342
|
+
if TracePoint.respond_to? :allow_reentry
|
343
|
+
def tp_allow_reentry
|
344
|
+
TracePoint.allow_reentry do
|
345
|
+
yield
|
346
|
+
end
|
347
|
+
rescue RuntimeError => e
|
348
|
+
# on the postmortem mode, it is not stopped in TracePoint
|
349
|
+
if e.message == 'No need to allow reentrance.'
|
350
|
+
yield
|
351
|
+
else
|
352
|
+
raise
|
353
|
+
end
|
354
|
+
end
|
355
|
+
else
|
356
|
+
def tp_allow_reentry
|
357
|
+
yield
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
def frame_eval_core src, b
|
362
|
+
saved_target_frames = @target_frames
|
363
|
+
saved_current_frame_index = @current_frame_index
|
364
|
+
|
365
|
+
if b
|
366
|
+
f, _l = b.source_location
|
367
|
+
|
368
|
+
tp_allow_reentry do
|
369
|
+
b.eval(src, "(rdbg)/#{f}")
|
370
|
+
end
|
371
|
+
else
|
372
|
+
frame_self = current_frame.self
|
373
|
+
|
374
|
+
tp_allow_reentry do
|
375
|
+
frame_self.instance_eval(src)
|
376
|
+
end
|
377
|
+
end
|
378
|
+
ensure
|
379
|
+
@target_frames = saved_target_frames
|
380
|
+
@current_frame_index = saved_current_frame_index
|
339
381
|
end
|
340
382
|
|
383
|
+
SPECIAL_LOCAL_VARS = [
|
384
|
+
[:raised_exception, "_raised"],
|
385
|
+
[:return_value, "_return"],
|
386
|
+
]
|
387
|
+
|
341
388
|
def frame_eval src, re_raise: false
|
342
|
-
|
343
|
-
@success_last_eval = false
|
389
|
+
@success_last_eval = false
|
344
390
|
|
345
|
-
|
391
|
+
b = current_frame.eval_binding
|
346
392
|
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
else
|
351
|
-
frame_self = current_frame.self
|
352
|
-
instance_eval_for_cmethod(frame_self, src)
|
353
|
-
end
|
354
|
-
@success_last_eval = true
|
355
|
-
result
|
393
|
+
special_local_variables current_frame do |name, var|
|
394
|
+
b.local_variable_set(name, var) if /\%/ !~ name
|
395
|
+
end
|
356
396
|
|
357
|
-
|
358
|
-
return yield(e) if block_given?
|
397
|
+
result = frame_eval_core(src, b)
|
359
398
|
|
360
|
-
|
399
|
+
@success_last_eval = true
|
400
|
+
result
|
361
401
|
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
402
|
+
rescue SystemExit
|
403
|
+
raise
|
404
|
+
rescue Exception => e
|
405
|
+
return yield(e) if block_given?
|
406
|
+
|
407
|
+
puts "eval error: #{e}"
|
408
|
+
|
409
|
+
e.backtrace_locations&.each do |loc|
|
410
|
+
break if loc.path == __FILE__
|
411
|
+
puts " #{loc}"
|
367
412
|
end
|
413
|
+
raise if re_raise
|
368
414
|
end
|
369
415
|
|
370
416
|
def show_src(frame_index: @current_frame_index,
|
371
417
|
update_line: false,
|
372
|
-
max_lines: 10,
|
418
|
+
max_lines: CONFIG[:show_src_lines] || 10,
|
373
419
|
start_line: nil,
|
374
420
|
end_line: nil,
|
375
421
|
dir: +1)
|
@@ -419,31 +465,50 @@ module DEBUGGER__
|
|
419
465
|
end
|
420
466
|
|
421
467
|
def current_frame
|
468
|
+
get_frame(@current_frame_index)
|
469
|
+
end
|
470
|
+
|
471
|
+
def get_frame(index)
|
422
472
|
if @target_frames
|
423
|
-
@target_frames[
|
473
|
+
@target_frames[index]
|
424
474
|
else
|
425
475
|
nil
|
426
476
|
end
|
427
477
|
end
|
428
478
|
|
429
|
-
|
479
|
+
def collect_locals(frame)
|
480
|
+
locals = []
|
430
481
|
|
431
|
-
|
432
|
-
|
433
|
-
puts_variable_info '%self', s, pat
|
482
|
+
if s = frame&.self
|
483
|
+
locals << ["%self", s]
|
434
484
|
end
|
435
|
-
|
436
|
-
|
437
|
-
end
|
438
|
-
if current_frame&.has_raised_exception
|
439
|
-
puts_variable_info "%raised", current_frame.raised_exception, pat
|
485
|
+
special_local_variables frame do |name, val|
|
486
|
+
locals << [name, val]
|
440
487
|
end
|
441
488
|
|
442
|
-
if vars =
|
489
|
+
if vars = frame&.local_variables
|
443
490
|
vars.each{|var, val|
|
444
|
-
|
491
|
+
locals << [var, val]
|
445
492
|
}
|
446
493
|
end
|
494
|
+
|
495
|
+
locals
|
496
|
+
end
|
497
|
+
|
498
|
+
## cmd: show
|
499
|
+
|
500
|
+
def special_local_variables frame
|
501
|
+
SPECIAL_LOCAL_VARS.each do |mid, name|
|
502
|
+
next unless frame&.send("has_#{mid}")
|
503
|
+
name = name.sub('_', '%') if frame.eval_binding.local_variable_defined?(name)
|
504
|
+
yield name, frame.send(mid)
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
508
|
+
def show_locals pat
|
509
|
+
collect_locals(current_frame).each do |var, val|
|
510
|
+
puts_variable_info(var, val, pat)
|
511
|
+
end
|
447
512
|
end
|
448
513
|
|
449
514
|
def show_ivars pat
|
@@ -508,28 +573,32 @@ module DEBUGGER__
|
|
508
573
|
w = SESSION::width
|
509
574
|
|
510
575
|
if mono_info.length >= w
|
511
|
-
|
576
|
+
maximum_value_width = w - "#{label} = ".length
|
577
|
+
valstr = truncate(inspected, width: maximum_value_width)
|
512
578
|
else
|
513
579
|
valstr = colored_inspect(obj, width: 2 ** 30)
|
514
580
|
valstr = inspected if valstr.lines.size > 1
|
515
|
-
info = "#{colorize_cyan(label)} = #{valstr}"
|
516
581
|
end
|
517
582
|
|
583
|
+
info = "#{colorize_cyan(label)} = #{valstr}"
|
584
|
+
|
518
585
|
puts info
|
519
586
|
end
|
520
587
|
|
521
588
|
def truncate(string, width:)
|
522
|
-
|
523
|
-
|
524
|
-
|
589
|
+
if string.start_with?("#<")
|
590
|
+
string[0 .. (width-5)] + '...>'
|
591
|
+
else
|
592
|
+
string[0 .. (width-4)] + '...'
|
593
|
+
end
|
525
594
|
end
|
526
595
|
|
527
596
|
### cmd: show edit
|
528
597
|
|
529
598
|
def show_by_editor path = nil
|
530
599
|
unless path
|
531
|
-
if
|
532
|
-
path =
|
600
|
+
if current_frame
|
601
|
+
path = current_frame.path
|
533
602
|
else
|
534
603
|
return # can't get path
|
535
604
|
end
|
@@ -633,8 +702,8 @@ module DEBUGGER__
|
|
633
702
|
def make_breakpoint args
|
634
703
|
case args.first
|
635
704
|
when :method
|
636
|
-
klass_name, op, method_name, cond, cmd = args[1..]
|
637
|
-
bp = MethodBreakpoint.new(current_frame.
|
705
|
+
klass_name, op, method_name, cond, cmd, path = args[1..]
|
706
|
+
bp = MethodBreakpoint.new(current_frame.eval_binding, klass_name, op, method_name, cond: cond, command: cmd, path: path)
|
638
707
|
begin
|
639
708
|
bp.enable
|
640
709
|
rescue Exception => e
|
@@ -644,8 +713,8 @@ module DEBUGGER__
|
|
644
713
|
|
645
714
|
bp
|
646
715
|
when :watch
|
647
|
-
ivar, object, result = args[1..]
|
648
|
-
WatchIVarBreakpoint.new(ivar, object, result)
|
716
|
+
ivar, object, result, cond, command, path = args[1..]
|
717
|
+
WatchIVarBreakpoint.new(ivar, object, result, cond: cond, command: command, path: path)
|
649
718
|
else
|
650
719
|
raise "unknown breakpoint: #{args}"
|
651
720
|
end
|
@@ -732,10 +801,11 @@ module DEBUGGER__
|
|
732
801
|
break
|
733
802
|
|
734
803
|
when :finish
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
804
|
+
finish_frames = (iter || 1) - 1
|
805
|
+
goal_depth = @target_frames.first.frame_depth - finish_frames
|
806
|
+
|
807
|
+
step_tp nil, [:return, :b_return] do
|
808
|
+
DEBUGGER__.frame_depth - 3 <= goal_depth ? true : false
|
739
809
|
end
|
740
810
|
break
|
741
811
|
|
@@ -834,6 +904,7 @@ module DEBUGGER__
|
|
834
904
|
else
|
835
905
|
raise "unsupported frame operation: #{arg.inspect}"
|
836
906
|
end
|
907
|
+
|
837
908
|
event! :result, nil
|
838
909
|
|
839
910
|
when :show
|
@@ -887,7 +958,7 @@ module DEBUGGER__
|
|
887
958
|
bp = make_breakpoint args
|
888
959
|
event! :result, :method_breakpoint, bp
|
889
960
|
when :watch
|
890
|
-
ivar = args[1]
|
961
|
+
ivar, cond, command, path = args[1..]
|
891
962
|
result = frame_eval(ivar)
|
892
963
|
|
893
964
|
if @success_last_eval
|
@@ -897,7 +968,7 @@ module DEBUGGER__
|
|
897
968
|
else
|
898
969
|
current_frame.self
|
899
970
|
end
|
900
|
-
bp = make_breakpoint [:watch, ivar, object, result]
|
971
|
+
bp = make_breakpoint [:watch, ivar, object, result, cond, command, path]
|
901
972
|
event! :result, :watch_breakpoint, bp
|
902
973
|
else
|
903
974
|
event! :result, nil
|
@@ -982,8 +1053,8 @@ module DEBUGGER__
|
|
982
1053
|
|
983
1054
|
@tp_recorder ||= TracePoint.new(:line){|tp|
|
984
1055
|
next unless Thread.current == thread
|
985
|
-
|
986
|
-
next if tp.path
|
1056
|
+
# can't be replaced by skip_location
|
1057
|
+
next if skip_internal_path?(tp.path)
|
987
1058
|
loc = caller_locations(1, 1).first
|
988
1059
|
next if skip_location?(loc)
|
989
1060
|
|
@@ -1067,7 +1138,7 @@ module DEBUGGER__
|
|
1067
1138
|
end
|
1068
1139
|
end
|
1069
1140
|
|
1070
|
-
#
|
1141
|
+
# copied from irb
|
1071
1142
|
class Output
|
1072
1143
|
include Color
|
1073
1144
|
|
data/lib/debug/tracer.rb
CHANGED
@@ -66,15 +66,7 @@ module DEBUGGER__
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def skip? tp
|
69
|
-
|
70
|
-
tp.path.start_with?('<internal:') ||
|
71
|
-
ThreadClient.current.management? ||
|
72
|
-
skip_path?(tp.path) ||
|
73
|
-
skip_with_pattern?(tp)
|
74
|
-
true
|
75
|
-
else
|
76
|
-
false
|
77
|
-
end
|
69
|
+
ThreadClient.current.management? || skip_path?(tp.path) || skip_with_pattern?(tp)
|
78
70
|
end
|
79
71
|
|
80
72
|
def skip_with_pattern?(tp)
|
@@ -89,11 +81,13 @@ module DEBUGGER__
|
|
89
81
|
ThreadClient.current.on_trace self.object_id, buff
|
90
82
|
else
|
91
83
|
@output.puts buff
|
84
|
+
@output.flush
|
92
85
|
end
|
93
86
|
end
|
94
87
|
|
95
88
|
def puts msg
|
96
89
|
@output.puts msg
|
90
|
+
@output.flush
|
97
91
|
end
|
98
92
|
|
99
93
|
def minfo tp
|
@@ -142,7 +136,7 @@ module DEBUGGER__
|
|
142
136
|
out tp, ">#{sp}#{call_identifier_str}", depth
|
143
137
|
when :return, :c_return, :b_return
|
144
138
|
depth += 1 if tp.event == :c_return
|
145
|
-
return_str = colorize_magenta(DEBUGGER__.
|
139
|
+
return_str = colorize_magenta(DEBUGGER__.safe_inspect(tp.return_value, short: true))
|
146
140
|
out tp, "<#{sp}#{call_identifier_str} #=> #{return_str}", depth
|
147
141
|
end
|
148
142
|
}
|
data/lib/debug/version.rb
CHANGED