debug 1.7.1 → 1.9.1
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 +2 -2
- data/README.md +50 -44
- data/Rakefile +8 -3
- data/debug.gemspec +3 -3
- data/ext/debug/debug.c +18 -4
- data/ext/debug/extconf.rb +1 -0
- data/ext/debug/iseq_collector.c +2 -0
- data/lib/debug/breakpoint.rb +6 -8
- data/lib/debug/client.rb +3 -2
- data/lib/debug/config.rb +35 -7
- data/lib/debug/console.rb +8 -29
- data/lib/debug/dap_custom/traceInspector.rb +336 -0
- data/lib/debug/frame_info.rb +9 -0
- data/lib/debug/irb_integration.rb +27 -0
- data/lib/debug/server.rb +9 -8
- data/lib/debug/server_cdp.rb +71 -72
- data/lib/debug/server_dap.rb +227 -179
- data/lib/debug/session.rb +105 -58
- data/lib/debug/source_repository.rb +3 -3
- data/lib/debug/thread_client.rb +51 -25
- data/lib/debug/tracer.rb +4 -5
- data/lib/debug/version.rb +1 -1
- data/misc/README.md.erb +42 -42
- metadata +12 -10
data/lib/debug/session.rb
CHANGED
@@ -82,7 +82,7 @@ class RubyVM::InstructionSequence
|
|
82
82
|
def first_line
|
83
83
|
self.to_a[4][:code_location][0]
|
84
84
|
end unless method_defined?(:first_line)
|
85
|
-
end
|
85
|
+
end if defined?(RubyVM::InstructionSequence)
|
86
86
|
|
87
87
|
module DEBUGGER__
|
88
88
|
PresetCommands = Struct.new(:commands, :source, :auto_continue)
|
@@ -128,16 +128,16 @@ module DEBUGGER__
|
|
128
128
|
@obj_map = {} # { object_id => ... } for CDP
|
129
129
|
|
130
130
|
@tp_thread_begin = nil
|
131
|
+
@tp_thread_end = nil
|
132
|
+
|
131
133
|
@commands = {}
|
132
134
|
@unsafe_context = false
|
133
135
|
|
134
|
-
has_keep_script_lines = RubyVM.
|
136
|
+
@has_keep_script_lines = defined?(RubyVM.keep_script_lines)
|
135
137
|
|
136
138
|
@tp_load_script = TracePoint.new(:script_compiled){|tp|
|
137
|
-
|
138
|
-
|
139
|
-
ThreadClient.current.on_load tp.instruction_sequence, eval_script
|
140
|
-
end
|
139
|
+
eval_script = tp.eval_script unless @has_keep_script_lines
|
140
|
+
ThreadClient.current.on_load tp.instruction_sequence, eval_script
|
141
141
|
}
|
142
142
|
@tp_load_script.enable
|
143
143
|
|
@@ -169,12 +169,17 @@ module DEBUGGER__
|
|
169
169
|
@ui = ui if ui
|
170
170
|
|
171
171
|
@tp_thread_begin&.disable
|
172
|
+
@tp_thread_end&.disable
|
172
173
|
@tp_thread_begin = nil
|
173
|
-
|
174
|
+
@tp_thread_end = nil
|
174
175
|
@ui.activate self, on_fork: on_fork
|
175
176
|
|
176
177
|
q = Queue.new
|
178
|
+
first_q = Queue.new
|
177
179
|
@session_server = Thread.new do
|
180
|
+
# make sure `@session_server` is assigned
|
181
|
+
first_q.pop; first_q = nil
|
182
|
+
|
178
183
|
Thread.current.name = 'DEBUGGER__::SESSION@server'
|
179
184
|
Thread.current.abort_on_exception = true
|
180
185
|
|
@@ -192,10 +197,21 @@ module DEBUGGER__
|
|
192
197
|
end
|
193
198
|
@tp_thread_begin.enable
|
194
199
|
|
200
|
+
@tp_thread_end = TracePoint.new(:thread_end) do |tp|
|
201
|
+
@th_clients.delete(Thread.current)
|
202
|
+
end
|
203
|
+
@tp_thread_end.enable
|
204
|
+
|
205
|
+
if CONFIG[:irb_console] && !CONFIG[:open]
|
206
|
+
require_relative "irb_integration"
|
207
|
+
thc.activate_irb_integration
|
208
|
+
end
|
209
|
+
|
195
210
|
# session start
|
196
211
|
q << true
|
197
212
|
session_server_main
|
198
213
|
end
|
214
|
+
first_q << :ok
|
199
215
|
|
200
216
|
q.pop
|
201
217
|
end
|
@@ -205,6 +221,7 @@ module DEBUGGER__
|
|
205
221
|
@thread_stopper.disable
|
206
222
|
@tp_load_script.disable
|
207
223
|
@tp_thread_begin.disable
|
224
|
+
@tp_thread_end.disable
|
208
225
|
@bps.each_value{|bp| bp.disable}
|
209
226
|
@th_clients.each_value{|thc| thc.close}
|
210
227
|
@tracers.values.each{|t| t.disable}
|
@@ -219,11 +236,13 @@ module DEBUGGER__
|
|
219
236
|
|
220
237
|
# activate new ui
|
221
238
|
@tp_thread_begin.disable
|
239
|
+
@tp_thread_end.disable
|
222
240
|
@ui.activate self
|
223
241
|
if @ui.respond_to?(:reader_thread) && thc = get_thread_client(@ui.reader_thread)
|
224
242
|
thc.mark_as_management
|
225
243
|
end
|
226
244
|
@tp_thread_begin.enable
|
245
|
+
@tp_thread_end.enable
|
227
246
|
end
|
228
247
|
|
229
248
|
def pop_event
|
@@ -242,6 +261,15 @@ module DEBUGGER__
|
|
242
261
|
@tc << req
|
243
262
|
end
|
244
263
|
|
264
|
+
def request_tc_with_restarted_threads(req)
|
265
|
+
restart_all_threads
|
266
|
+
request_tc(req)
|
267
|
+
end
|
268
|
+
|
269
|
+
def request_eval type, src
|
270
|
+
request_tc_with_restarted_threads [:eval, type, src]
|
271
|
+
end
|
272
|
+
|
245
273
|
def process_event evt
|
246
274
|
# variable `@internal_info` is only used for test
|
247
275
|
tc, output, ev, @internal_info, *ev_args = evt
|
@@ -300,7 +328,7 @@ module DEBUGGER__
|
|
300
328
|
if @displays.empty?
|
301
329
|
wait_command_loop
|
302
330
|
else
|
303
|
-
|
331
|
+
request_eval :display, @displays
|
304
332
|
end
|
305
333
|
when :result
|
306
334
|
raise "[BUG] not in subsession" if @subsession_stack.empty?
|
@@ -315,6 +343,7 @@ module DEBUGGER__
|
|
315
343
|
end
|
316
344
|
end
|
317
345
|
|
346
|
+
stop_all_threads
|
318
347
|
when :method_breakpoint, :watch_breakpoint
|
319
348
|
bp = ev_args[1]
|
320
349
|
if bp
|
@@ -328,17 +357,15 @@ module DEBUGGER__
|
|
328
357
|
obj_inspect = ev_args[2]
|
329
358
|
opt = ev_args[3]
|
330
359
|
add_tracer ObjectTracer.new(@ui, obj_id, obj_inspect, **opt)
|
360
|
+
stop_all_threads
|
331
361
|
else
|
332
|
-
|
362
|
+
stop_all_threads
|
333
363
|
end
|
334
364
|
|
335
365
|
wait_command_loop
|
336
366
|
|
337
|
-
when :
|
338
|
-
|
339
|
-
wait_command_loop
|
340
|
-
when :cdp_result
|
341
|
-
cdp_event ev_args
|
367
|
+
when :protocol_result
|
368
|
+
process_protocol_result ev_args
|
342
369
|
wait_command_loop
|
343
370
|
end
|
344
371
|
end
|
@@ -480,9 +507,9 @@ module DEBUGGER__
|
|
480
507
|
# * `u[ntil]`
|
481
508
|
# * Similar to `next` command, but only stop later lines or the end of the current frame.
|
482
509
|
# * Similar to gdb's `advance` command.
|
483
|
-
# * `u[ntil] <[file:]line
|
510
|
+
# * `u[ntil] <[file:]line>`
|
484
511
|
# * Run til the program reaches given location or the end of the current frame.
|
485
|
-
# * `u[ntil] <name
|
512
|
+
# * `u[ntil] <name>`
|
486
513
|
# * Run til the program invokes a method `<name>`. `<name>` can be a regexp with `/name/`.
|
487
514
|
register_command 'u', 'until',
|
488
515
|
repeat: true,
|
@@ -674,15 +701,15 @@ module DEBUGGER__
|
|
674
701
|
register_command 'bt', 'backtrace', unsafe: false do |arg|
|
675
702
|
case arg
|
676
703
|
when /\A(\d+)\z/
|
677
|
-
|
704
|
+
request_tc_with_restarted_threads [:show, :backtrace, arg.to_i, nil]
|
678
705
|
when /\A\/(.*)\/\z/
|
679
706
|
pattern = $1
|
680
|
-
|
707
|
+
request_tc_with_restarted_threads [:show, :backtrace, nil, Regexp.compile(pattern)]
|
681
708
|
when /\A(\d+)\s+\/(.*)\/\z/
|
682
709
|
max, pattern = $1, $2
|
683
|
-
|
710
|
+
request_tc_with_restarted_threads [:show, :backtrace, max.to_i, Regexp.compile(pattern)]
|
684
711
|
else
|
685
|
-
|
712
|
+
request_tc_with_restarted_threads [:show, :backtrace, nil, nil]
|
686
713
|
end
|
687
714
|
end
|
688
715
|
|
@@ -799,15 +826,15 @@ module DEBUGGER__
|
|
799
826
|
|
800
827
|
case sub
|
801
828
|
when nil
|
802
|
-
|
829
|
+
request_tc_with_restarted_threads [:show, :default, pat] # something useful
|
803
830
|
when :locals
|
804
|
-
|
831
|
+
request_tc_with_restarted_threads [:show, :locals, pat]
|
805
832
|
when :ivars
|
806
|
-
|
833
|
+
request_tc_with_restarted_threads [:show, :ivars, pat, opt]
|
807
834
|
when :consts
|
808
|
-
|
835
|
+
request_tc_with_restarted_threads [:show, :consts, pat, opt]
|
809
836
|
when :globals
|
810
|
-
|
837
|
+
request_tc_with_restarted_threads [:show, :globals, pat]
|
811
838
|
when :threads
|
812
839
|
thread_list
|
813
840
|
:retry
|
@@ -827,7 +854,7 @@ module DEBUGGER__
|
|
827
854
|
# * Show you available methods and instance variables of the given object.
|
828
855
|
# * If the object is a class/module, it also lists its constants.
|
829
856
|
register_command 'outline', 'o', 'ls', unsafe: false do |arg|
|
830
|
-
|
857
|
+
request_tc_with_restarted_threads [:show, :outline, arg]
|
831
858
|
end
|
832
859
|
|
833
860
|
# * `display`
|
@@ -837,9 +864,9 @@ module DEBUGGER__
|
|
837
864
|
register_command 'display', postmortem: false do |arg|
|
838
865
|
if arg && !arg.empty?
|
839
866
|
@displays << arg
|
840
|
-
|
867
|
+
request_eval :try_display, @displays
|
841
868
|
else
|
842
|
-
|
869
|
+
request_eval :display, @displays
|
843
870
|
end
|
844
871
|
end
|
845
872
|
|
@@ -853,7 +880,7 @@ module DEBUGGER__
|
|
853
880
|
if @displays[n = $1.to_i]
|
854
881
|
@displays.delete_at n
|
855
882
|
end
|
856
|
-
|
883
|
+
request_eval :display, @displays
|
857
884
|
when nil
|
858
885
|
if ask "clear all?", 'N'
|
859
886
|
@displays.clear
|
@@ -889,13 +916,13 @@ module DEBUGGER__
|
|
889
916
|
# * `p <expr>`
|
890
917
|
# * Evaluate like `p <expr>` on the current frame.
|
891
918
|
register_command 'p' do |arg|
|
892
|
-
|
919
|
+
request_eval :p, arg.to_s
|
893
920
|
end
|
894
921
|
|
895
922
|
# * `pp <expr>`
|
896
923
|
# * Evaluate like `pp <expr>` on the current frame.
|
897
924
|
register_command 'pp' do |arg|
|
898
|
-
|
925
|
+
request_eval :pp, arg.to_s
|
899
926
|
end
|
900
927
|
|
901
928
|
# * `eval <expr>`
|
@@ -906,7 +933,7 @@ module DEBUGGER__
|
|
906
933
|
@ui.puts "\nTo evaluate the variable `#{cmd}`, use `pp #{cmd}` instead."
|
907
934
|
:retry
|
908
935
|
else
|
909
|
-
|
936
|
+
request_eval :call, arg
|
910
937
|
end
|
911
938
|
end
|
912
939
|
|
@@ -914,10 +941,11 @@ module DEBUGGER__
|
|
914
941
|
# * Invoke `irb` on the current frame.
|
915
942
|
register_command 'irb' do |arg|
|
916
943
|
if @ui.remote?
|
917
|
-
@ui.puts "not supported on the remote console."
|
944
|
+
@ui.puts "\nIRB is not supported on the remote console."
|
918
945
|
:retry
|
946
|
+
else
|
947
|
+
request_eval :irb, nil
|
919
948
|
end
|
920
|
-
request_tc [:eval, :irb]
|
921
949
|
end
|
922
950
|
|
923
951
|
### Trace
|
@@ -972,7 +1000,7 @@ module DEBUGGER__
|
|
972
1000
|
:retry
|
973
1001
|
|
974
1002
|
when /\Aobject\s+(.+)/
|
975
|
-
|
1003
|
+
request_tc_with_restarted_threads [:trace, :object, $1.strip, {pattern: pattern, into: into}]
|
976
1004
|
|
977
1005
|
when /\Aoff\s+(\d+)\z/
|
978
1006
|
if t = @tracers.values[$1.to_i]
|
@@ -1137,7 +1165,7 @@ module DEBUGGER__
|
|
1137
1165
|
@repl_prev_line = nil
|
1138
1166
|
check_unsafe
|
1139
1167
|
|
1140
|
-
|
1168
|
+
request_eval :pp, line
|
1141
1169
|
end
|
1142
1170
|
|
1143
1171
|
rescue Interrupt
|
@@ -1321,10 +1349,6 @@ module DEBUGGER__
|
|
1321
1349
|
|
1322
1350
|
# breakpoint management
|
1323
1351
|
|
1324
|
-
def bps_pending_until_load?
|
1325
|
-
@bps.any?{|key, bp| bp.pending_until_load?}
|
1326
|
-
end
|
1327
|
-
|
1328
1352
|
def iterate_bps
|
1329
1353
|
deleted_bps = []
|
1330
1354
|
i = 0
|
@@ -1500,7 +1524,7 @@ module DEBUGGER__
|
|
1500
1524
|
def clear_line_breakpoints path
|
1501
1525
|
path = resolve_path(path)
|
1502
1526
|
clear_breakpoints do |k, bp|
|
1503
|
-
bp.is_a?(LineBreakpoint) &&
|
1527
|
+
bp.is_a?(LineBreakpoint) && bp.path_is?(path)
|
1504
1528
|
end
|
1505
1529
|
rescue Errno::ENOENT
|
1506
1530
|
# just ignore
|
@@ -1524,7 +1548,7 @@ module DEBUGGER__
|
|
1524
1548
|
# tracers
|
1525
1549
|
|
1526
1550
|
def add_tracer tracer
|
1527
|
-
if @tracers
|
1551
|
+
if @tracers[tracer.key]&.enabled?
|
1528
1552
|
tracer.disable
|
1529
1553
|
@ui.puts "Duplicated tracer: #{tracer}"
|
1530
1554
|
else
|
@@ -1724,25 +1748,30 @@ module DEBUGGER__
|
|
1724
1748
|
file_path, reloaded = @sr.add(iseq, src)
|
1725
1749
|
@ui.event :load, file_path, reloaded
|
1726
1750
|
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1751
|
+
# check breakpoints
|
1752
|
+
if file_path
|
1753
|
+
@bps.find_all do |_key, bp|
|
1754
|
+
LineBreakpoint === bp && bp.path_is?(file_path) && (iseq.first_lineno..iseq.last_line).cover?(bp.line)
|
1755
|
+
end.each do |_key, bp|
|
1756
|
+
if !bp.iseq
|
1757
|
+
bp.try_activate iseq
|
1758
|
+
elsif reloaded
|
1759
|
+
@bps.delete bp.key # to allow duplicate
|
1730
1760
|
|
1731
|
-
|
1732
|
-
|
1733
|
-
|
1734
|
-
end
|
1735
|
-
end
|
1761
|
+
# When we delete a breakpoint from the @bps hash, we also need to deactivate it or else its tracepoint event
|
1762
|
+
# will continue to be enabled and we'll suspend on ghost breakpoints
|
1763
|
+
bp.delete
|
1736
1764
|
|
1737
|
-
|
1738
|
-
@bps.find_all do |key, bp|
|
1739
|
-
LineBreakpoint === bp && DEBUGGER__.compare_path(bp.path, file_path)
|
1740
|
-
end.each do |_key, bp|
|
1741
|
-
@bps.delete bp.key # to allow duplicate
|
1742
|
-
if nbp = LineBreakpoint.copy(bp, iseq)
|
1765
|
+
nbp = LineBreakpoint.copy(bp, iseq)
|
1743
1766
|
add_bp nbp
|
1744
1767
|
end
|
1745
1768
|
end
|
1769
|
+
else # !file_path => file_path is not existing
|
1770
|
+
@bps.find_all do |_key, bp|
|
1771
|
+
LineBreakpoint === bp && !bp.iseq && DEBUGGER__.compare_path(bp.path, (iseq.absolute_path || iseq.path))
|
1772
|
+
end.each do |_key, bp|
|
1773
|
+
bp.try_activate iseq
|
1774
|
+
end
|
1746
1775
|
end
|
1747
1776
|
end
|
1748
1777
|
|
@@ -1980,6 +2009,13 @@ module DEBUGGER__
|
|
1980
2009
|
def after_fork_parent
|
1981
2010
|
@ui.after_fork_parent
|
1982
2011
|
end
|
2012
|
+
|
2013
|
+
# experimental API
|
2014
|
+
def extend_feature session: nil, thread_client: nil, ui: nil
|
2015
|
+
Session.include session if session
|
2016
|
+
ThreadClient.include thread_client if thread_client
|
2017
|
+
@ui.extend ui if ui
|
2018
|
+
end
|
1983
2019
|
end
|
1984
2020
|
|
1985
2021
|
class ProcessGroup
|
@@ -2154,6 +2190,7 @@ module DEBUGGER__
|
|
2154
2190
|
case loc.absolute_path
|
2155
2191
|
when dir_prefix
|
2156
2192
|
when %r{rubygems/core_ext/kernel_require\.rb}
|
2193
|
+
when %r{bundled_gems\.rb}
|
2157
2194
|
else
|
2158
2195
|
return loc if loc.absolute_path
|
2159
2196
|
end
|
@@ -2438,7 +2475,7 @@ module DEBUGGER__
|
|
2438
2475
|
end
|
2439
2476
|
|
2440
2477
|
module DaemonInterceptor
|
2441
|
-
def daemon
|
2478
|
+
def daemon(*args)
|
2442
2479
|
return super unless defined?(SESSION) && SESSION.active?
|
2443
2480
|
|
2444
2481
|
_, child_hook = __fork_setup_for_debugger(:child)
|
@@ -2504,7 +2541,17 @@ module DEBUGGER__
|
|
2504
2541
|
|
2505
2542
|
module TrapInterceptor
|
2506
2543
|
def trap sig, *command, &command_proc
|
2507
|
-
|
2544
|
+
sym =
|
2545
|
+
case sig
|
2546
|
+
when String
|
2547
|
+
sig.to_sym
|
2548
|
+
when Integer
|
2549
|
+
Signal.signame(sig)&.to_sym
|
2550
|
+
else
|
2551
|
+
sig
|
2552
|
+
end
|
2553
|
+
|
2554
|
+
case sym
|
2508
2555
|
when :INT, :SIGINT
|
2509
2556
|
if defined?(SESSION) && SESSION.active? && SESSION.intercept_trap_sigint?
|
2510
2557
|
return SESSION.save_int_trap(command.empty? ? command_proc : command.first)
|
@@ -22,7 +22,7 @@ module DEBUGGER__
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
if RubyVM.
|
25
|
+
if defined?(RubyVM.keep_script_lines)
|
26
26
|
# Ruby 3.1 and later
|
27
27
|
RubyVM.keep_script_lines = true
|
28
28
|
require 'objspace'
|
@@ -34,7 +34,7 @@ module DEBUGGER__
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def add iseq, src
|
37
|
-
#
|
37
|
+
# only manage loaded file names
|
38
38
|
if (path = (iseq.absolute_path || iseq.path)) && File.exist?(path)
|
39
39
|
if @loaded_file_map.has_key? path
|
40
40
|
return path, true # reloaded
|
@@ -49,7 +49,7 @@ module DEBUGGER__
|
|
49
49
|
lines = iseq.script_lines&.map(&:chomp)
|
50
50
|
line = iseq.first_line
|
51
51
|
if line > 1
|
52
|
-
|
52
|
+
[*([''] * (line - 1)), *lines]
|
53
53
|
else
|
54
54
|
lines
|
55
55
|
end
|
data/lib/debug/thread_client.rb
CHANGED
@@ -5,6 +5,10 @@ require 'pp'
|
|
5
5
|
|
6
6
|
require_relative 'color'
|
7
7
|
|
8
|
+
class ::Thread
|
9
|
+
attr_accessor :debug_thread_client
|
10
|
+
end
|
11
|
+
|
8
12
|
module DEBUGGER__
|
9
13
|
M_INSTANCE_VARIABLES = method(:instance_variables).unbind
|
10
14
|
M_INSTANCE_VARIABLE_GET = method(:instance_variable_get).unbind
|
@@ -14,6 +18,7 @@ module DEBUGGER__
|
|
14
18
|
M_RESPOND_TO_P = method(:respond_to?).unbind
|
15
19
|
M_METHOD = method(:method).unbind
|
16
20
|
M_OBJECT_ID = method(:object_id).unbind
|
21
|
+
M_NAME = method(:name).unbind
|
17
22
|
|
18
23
|
module SkipPathHelper
|
19
24
|
def skip_path?(path)
|
@@ -47,12 +52,7 @@ module DEBUGGER__
|
|
47
52
|
|
48
53
|
class ThreadClient
|
49
54
|
def self.current
|
50
|
-
|
51
|
-
thc
|
52
|
-
else
|
53
|
-
thc = SESSION.get_thread_client
|
54
|
-
Thread.current[:DEBUGGER__ThreadClient] = thc
|
55
|
-
end
|
55
|
+
Thread.current.debug_thread_client ||= SESSION.get_thread_client
|
56
56
|
end
|
57
57
|
|
58
58
|
include Color
|
@@ -468,10 +468,14 @@ module DEBUGGER__
|
|
468
468
|
if file_lines = frame.file_lines
|
469
469
|
frame_line = frame.location.lineno - 1
|
470
470
|
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
471
|
+
if CONFIG[:no_lineno]
|
472
|
+
lines = file_lines
|
473
|
+
else
|
474
|
+
lines = file_lines.map.with_index do |e, i|
|
475
|
+
cur = i == frame_line ? '=>' : ' '
|
476
|
+
line = colorize_dim('%4d|' % (i+1))
|
477
|
+
"#{cur}#{line} #{e}"
|
478
|
+
end
|
475
479
|
end
|
476
480
|
|
477
481
|
unless start_line
|
@@ -607,12 +611,17 @@ module DEBUGGER__
|
|
607
611
|
|
608
612
|
def get_consts expr = nil, only_self: false, &block
|
609
613
|
if expr && !expr.empty?
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
+
begin
|
615
|
+
_self = frame_eval(expr, re_raise: true)
|
616
|
+
rescue Exception
|
617
|
+
# ignore
|
614
618
|
else
|
615
|
-
|
619
|
+
if M_KIND_OF_P.bind_call(_self, Module)
|
620
|
+
iter_consts _self, &block
|
621
|
+
return
|
622
|
+
else
|
623
|
+
puts "#{_self.inspect} (by #{expr}) is not a Module."
|
624
|
+
end
|
616
625
|
end
|
617
626
|
elsif _self = current_frame&.self
|
618
627
|
cs = {}
|
@@ -852,8 +861,18 @@ module DEBUGGER__
|
|
852
861
|
class SuspendReplay < Exception
|
853
862
|
end
|
854
863
|
|
864
|
+
if ::Fiber.respond_to?(:blocking)
|
865
|
+
private def fiber_blocking
|
866
|
+
::Fiber.blocking{yield}
|
867
|
+
end
|
868
|
+
else
|
869
|
+
private def fiber_blocking
|
870
|
+
yield
|
871
|
+
end
|
872
|
+
end
|
873
|
+
|
855
874
|
def wait_next_action
|
856
|
-
wait_next_action_
|
875
|
+
fiber_blocking{wait_next_action_}
|
857
876
|
rescue SuspendReplay
|
858
877
|
replay_suspend
|
859
878
|
end
|
@@ -1038,13 +1057,8 @@ module DEBUGGER__
|
|
1038
1057
|
when :call
|
1039
1058
|
result = frame_eval(eval_src)
|
1040
1059
|
when :irb
|
1041
|
-
|
1042
|
-
|
1043
|
-
result = frame_eval('binding.irb(show_code: false)', binding_location: true)
|
1044
|
-
ensure
|
1045
|
-
# workaround: https://github.com/ruby/debug/issues/308
|
1046
|
-
Reline.prompt_proc = nil if defined? Reline
|
1047
|
-
end
|
1060
|
+
require_relative "irb_integration"
|
1061
|
+
activate_irb_integration
|
1048
1062
|
when :display, :try_display
|
1049
1063
|
failed_results = []
|
1050
1064
|
eval_src.each_with_index{|src, i|
|
@@ -1230,7 +1244,15 @@ module DEBUGGER__
|
|
1230
1244
|
rescue SuspendReplay, SystemExit, Interrupt
|
1231
1245
|
raise
|
1232
1246
|
rescue Exception => e
|
1233
|
-
|
1247
|
+
STDERR.puts e.cause.inspect
|
1248
|
+
STDERR.puts e.inspect
|
1249
|
+
Thread.list.each{|th|
|
1250
|
+
STDERR.puts "@@@ #{th}"
|
1251
|
+
th.backtrace.each{|b|
|
1252
|
+
STDERR.puts " > #{b}"
|
1253
|
+
}
|
1254
|
+
}
|
1255
|
+
p ["DEBUGGER Exception: #{__FILE__}:#{__LINE__}", e, e.backtrace]
|
1234
1256
|
raise
|
1235
1257
|
ensure
|
1236
1258
|
@returning = false
|
@@ -1292,10 +1314,14 @@ module DEBUGGER__
|
|
1292
1314
|
frame._callee = b.eval('__callee__')
|
1293
1315
|
end
|
1294
1316
|
}
|
1295
|
-
|
1317
|
+
append(frames)
|
1296
1318
|
}
|
1297
1319
|
end
|
1298
1320
|
|
1321
|
+
def append frames
|
1322
|
+
@log << frames
|
1323
|
+
end
|
1324
|
+
|
1299
1325
|
def enable
|
1300
1326
|
unless @tp_recorder.enabled?
|
1301
1327
|
@log.clear
|
data/lib/debug/tracer.rb
CHANGED
@@ -54,6 +54,10 @@ module DEBUGGER__
|
|
54
54
|
@tracer.disable
|
55
55
|
end
|
56
56
|
|
57
|
+
def enabled?
|
58
|
+
@tracer.enabled?
|
59
|
+
end
|
60
|
+
|
57
61
|
def description
|
58
62
|
nil
|
59
63
|
end
|
@@ -85,11 +89,6 @@ module DEBUGGER__
|
|
85
89
|
end
|
86
90
|
end
|
87
91
|
|
88
|
-
def puts msg
|
89
|
-
@output.puts msg
|
90
|
-
@output.flush
|
91
|
-
end
|
92
|
-
|
93
92
|
def minfo tp
|
94
93
|
return "block{}" if tp.event == :b_call
|
95
94
|
|
data/lib/debug/version.rb
CHANGED