debug 1.9.2 → 1.11.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/README.md +122 -92
- data/debug.gemspec +1 -0
- data/lib/debug/config.rb +41 -35
- data/lib/debug/console.rb +22 -11
- data/lib/debug/frame_info.rb +3 -1
- data/lib/debug/server.rb +10 -1
- data/lib/debug/server_cdp.rb +1 -1
- data/lib/debug/server_dap.rb +1 -1
- data/lib/debug/session.rb +15 -7
- data/lib/debug/thread_client.rb +6 -4
- data/lib/debug/version.rb +1 -1
- data/misc/README.md.erb +117 -91
- metadata +4 -3
data/lib/debug/config.rb
CHANGED
@@ -12,49 +12,52 @@ module DEBUGGER__
|
|
12
12
|
|
13
13
|
CONFIG_SET = {
|
14
14
|
# UI setting
|
15
|
-
log_level:
|
16
|
-
show_src_lines:
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
15
|
+
log_level: ['RUBY_DEBUG_LOG_LEVEL', "UI: Log level same as Logger", :loglevel, "WARN"],
|
16
|
+
show_src_lines: ['RUBY_DEBUG_SHOW_SRC_LINES', "UI: Show n lines source code on breakpoint", :int, "10"],
|
17
|
+
show_src_lines_frame:['RUBY_DEBUG_SHOW_SRC_LINES_FRAME', "UI: Show n lines source code on frame operations", :int, "1"],
|
18
|
+
show_evaledsrc: ['RUBY_DEBUG_SHOW_EVALEDSRC', "UI: Show actually evaluated source", :bool, "false"],
|
19
|
+
show_frames: ['RUBY_DEBUG_SHOW_FRAMES', "UI: Show n frames on breakpoint", :int, "2"],
|
20
|
+
use_short_path: ['RUBY_DEBUG_USE_SHORT_PATH', "UI: Show shorten PATH (like $(Gem)/foo.rb)", :bool, "false"],
|
21
|
+
no_color: ['RUBY_DEBUG_NO_COLOR', "UI: Do not use colorize", :bool, "false"],
|
22
|
+
no_sigint_hook: ['RUBY_DEBUG_NO_SIGINT_HOOK', "UI: Do not suspend on SIGINT", :bool, "false"],
|
23
|
+
no_reline: ['RUBY_DEBUG_NO_RELINE', "UI: Do not use Reline library", :bool, "false"],
|
24
|
+
no_hint: ['RUBY_DEBUG_NO_HINT', "UI: Do not show the hint on the REPL", :bool, "false"],
|
25
|
+
no_lineno: ['RUBY_DEBUG_NO_LINENO', "UI: Do not show line numbers", :bool, "false"],
|
26
|
+
no_repeat: ['RUBY_DEBUG_NO_REPEAT', "UI: Do not repeat last line when empty line",:bool, "false"],
|
27
|
+
irb_console: ["RUBY_DEBUG_IRB_CONSOLE", "UI: Use IRB as the console", :bool, "false"],
|
26
28
|
|
27
29
|
# control setting
|
28
|
-
skip_path:
|
29
|
-
skip_nosrc:
|
30
|
-
keep_alloc_site:['RUBY_DEBUG_KEEP_ALLOC_SITE',"CONTROL: Keep allocation site and p, pp shows it", :bool, "false"],
|
31
|
-
postmortem:
|
32
|
-
fork_mode:
|
33
|
-
sigdump_sig:
|
30
|
+
skip_path: ['RUBY_DEBUG_SKIP_PATH', "CONTROL: Skip showing/entering frames for given paths", :path],
|
31
|
+
skip_nosrc: ['RUBY_DEBUG_SKIP_NOSRC', "CONTROL: Skip on no source code lines", :bool, "false"],
|
32
|
+
keep_alloc_site: ['RUBY_DEBUG_KEEP_ALLOC_SITE',"CONTROL: Keep allocation site and p, pp shows it", :bool, "false"],
|
33
|
+
postmortem: ['RUBY_DEBUG_POSTMORTEM', "CONTROL: Enable postmortem debug", :bool, "false"],
|
34
|
+
fork_mode: ['RUBY_DEBUG_FORK_MODE', "CONTROL: Control which process activates a debugger after fork (both/parent/child)", :forkmode, "both"],
|
35
|
+
sigdump_sig: ['RUBY_DEBUG_SIGDUMP_SIG', "CONTROL: Sigdump signal", :bool, "false"],
|
34
36
|
|
35
37
|
# boot setting
|
36
|
-
nonstop:
|
37
|
-
stop_at_load:
|
38
|
-
init_script:
|
39
|
-
commands:
|
40
|
-
no_rc:
|
41
|
-
history_file:
|
42
|
-
save_history:
|
38
|
+
nonstop: ['RUBY_DEBUG_NONSTOP', "BOOT: Nonstop mode", :bool, "false"],
|
39
|
+
stop_at_load: ['RUBY_DEBUG_STOP_AT_LOAD',"BOOT: Stop at just loading location", :bool, "false"],
|
40
|
+
init_script: ['RUBY_DEBUG_INIT_SCRIPT', "BOOT: debug command script path loaded at first stop"],
|
41
|
+
commands: ['RUBY_DEBUG_COMMANDS', "BOOT: debug commands invoked at first stop. Commands should be separated by `;;`"],
|
42
|
+
no_rc: ['RUBY_DEBUG_NO_RC', "BOOT: ignore loading ~/.rdbgrc(.rb)", :bool, "false"],
|
43
|
+
history_file: ['RUBY_DEBUG_HISTORY_FILE',"BOOT: history file (default: ${XDG_STATE_HOME-~/.local/state}/rdbg/history)", :string, nil],
|
44
|
+
save_history: ['RUBY_DEBUG_SAVE_HISTORY',"BOOT: maximum save history lines", :int, "10000"],
|
43
45
|
|
44
46
|
# remote setting
|
45
|
-
open:
|
46
|
-
port:
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
47
|
+
open: ['RUBY_DEBUG_OPEN', "REMOTE: Open remote port (same as `rdbg --open` option)"],
|
48
|
+
port: ['RUBY_DEBUG_PORT', "REMOTE: TCP/IP remote debugging: port"],
|
49
|
+
port_range: ['RUBY_DEBUG_PORT_RANGE', "REMOTE: TCP/IP remote debugging: length of port range"],
|
50
|
+
host: ['RUBY_DEBUG_HOST', "REMOTE: TCP/IP remote debugging: host", :string, "127.0.0.1"],
|
51
|
+
sock_path: ['RUBY_DEBUG_SOCK_PATH', "REMOTE: UNIX Domain Socket remote debugging: socket path"],
|
52
|
+
sock_dir: ['RUBY_DEBUG_SOCK_DIR', "REMOTE: UNIX Domain Socket remote debugging: socket directory"],
|
53
|
+
local_fs_map: ['RUBY_DEBUG_LOCAL_FS_MAP', "REMOTE: Specify local fs map", :path_map],
|
54
|
+
skip_bp: ['RUBY_DEBUG_SKIP_BP', "REMOTE: Skip breakpoints if no clients are attached", :bool, 'false'],
|
55
|
+
cookie: ['RUBY_DEBUG_COOKIE', "REMOTE: Cookie for negotiation"],
|
56
|
+
session_name: ['RUBY_DEBUG_SESSION_NAME', "REMOTE: Session name for differentiating multiple sessions"],
|
57
|
+
chrome_path: ['RUBY_DEBUG_CHROME_PATH', "REMOTE: Platform dependent path of Chrome (For more information, See [here](https://github.com/ruby/debug/pull/334/files#diff-5fc3d0a901379a95bc111b86cf0090b03f857edfd0b99a0c1537e26735698453R55-R64))"],
|
55
58
|
|
56
59
|
# obsolete
|
57
|
-
parent_on_fork:
|
60
|
+
parent_on_fork: ['RUBY_DEBUG_PARENT_ON_FORK', "OBSOLETE: Keep debugging parent process on fork", :bool, "false"],
|
58
61
|
}.freeze
|
59
62
|
|
60
63
|
CONFIG_MAP = CONFIG_SET.map{|k, (ev, _)| [k, ev]}.to_h.freeze
|
@@ -352,6 +355,9 @@ module DEBUGGER__
|
|
352
355
|
o.on('--port=PORT', 'Listening TCP/IP port') do |port|
|
353
356
|
config[:port] = port
|
354
357
|
end
|
358
|
+
o.on('--port-range=PORT_RANGE', 'Number of ports to try to connect to') do |port_range|
|
359
|
+
config[:port_range] = port_range
|
360
|
+
end
|
355
361
|
o.on('--host=HOST', 'Listening TCP/IP host') do |host|
|
356
362
|
config[:host] = host
|
357
363
|
end
|
data/lib/debug/console.rb
CHANGED
@@ -153,21 +153,28 @@ module DEBUGGER__
|
|
153
153
|
end
|
154
154
|
|
155
155
|
def history_file
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
156
|
+
case
|
157
|
+
when (path = CONFIG[:history_file]) && !path.empty?
|
158
|
+
path = File.expand_path(path)
|
159
|
+
when (path = File.expand_path("~/.rdbg_history")) && File.exist?(path) # for compatibility
|
160
|
+
# path
|
160
161
|
else
|
161
|
-
|
162
|
+
state_dir = ENV['XDG_STATE_HOME'] || File.join(Dir.home, '.local', 'state')
|
163
|
+
path = File.join(File.expand_path(state_dir), 'rdbg', 'history')
|
162
164
|
end
|
165
|
+
|
166
|
+
FileUtils.mkdir_p(File.dirname(path)) unless File.exist?(path)
|
167
|
+
path
|
163
168
|
end
|
164
169
|
|
165
170
|
FH = "# Today's OMIKUJI: "
|
166
171
|
|
167
172
|
def read_history_file
|
168
|
-
if history && File.exist?(path = history_file)
|
173
|
+
if history && File.exist?(path = history_file())
|
169
174
|
f = (['', 'DAI-', 'CHU-', 'SHO-'].map{|e| e+'KICHI'}+['KYO']).sample
|
170
|
-
|
175
|
+
# Read history file and scrub invalid characters to prevent encoding errors
|
176
|
+
lines = File.readlines(path).map(&:scrub)
|
177
|
+
["#{FH}#{f}".dup] + lines
|
171
178
|
else
|
172
179
|
[]
|
173
180
|
end
|
@@ -186,15 +193,17 @@ module DEBUGGER__
|
|
186
193
|
def deactivate
|
187
194
|
if history && @init_history_lines
|
188
195
|
added_records = history.to_a[@init_history_lines .. -1]
|
189
|
-
path = history_file
|
196
|
+
path = history_file()
|
190
197
|
max = CONFIG[:save_history]
|
191
198
|
|
192
199
|
if !added_records.empty? && !path.empty?
|
193
200
|
orig_records = read_history_file
|
194
|
-
open(history_file, 'w'){|f|
|
201
|
+
open(history_file(), 'w'){|f|
|
195
202
|
(orig_records + added_records).last(max).each{|line|
|
196
|
-
|
197
|
-
|
203
|
+
# Use scrub to handle encoding issues gracefully
|
204
|
+
scrubbed_line = line.scrub.strip
|
205
|
+
if !line.start_with?(FH) && !scrubbed_line.empty?
|
206
|
+
f.puts scrubbed_line
|
198
207
|
end
|
199
208
|
}
|
200
209
|
}
|
@@ -204,6 +213,8 @@ module DEBUGGER__
|
|
204
213
|
|
205
214
|
def load_history
|
206
215
|
read_history_file.each{|line|
|
216
|
+
# Use scrub to handle encoding issues gracefully, then strip
|
217
|
+
line.scrub!
|
207
218
|
line.strip!
|
208
219
|
history << line unless line.empty?
|
209
220
|
} if history.empty?
|
data/lib/debug/frame_info.rb
CHANGED
@@ -86,7 +86,9 @@ module DEBUGGER__
|
|
86
86
|
|
87
87
|
def block_identifier
|
88
88
|
return unless frame_type == :block
|
89
|
-
|
89
|
+
re_match = location.label.match(BLOCK_LABL_REGEXP)
|
90
|
+
_, level, block_loc = re_match ? re_match.to_a : [nil, nil, location.label]
|
91
|
+
|
90
92
|
[level || "", block_loc]
|
91
93
|
end
|
92
94
|
|
data/lib/debug/server.rb
CHANGED
@@ -399,6 +399,13 @@ module DEBUGGER__
|
|
399
399
|
raise "Specify digits for port number"
|
400
400
|
end
|
401
401
|
end
|
402
|
+
@port_range = if @port.zero?
|
403
|
+
0
|
404
|
+
else
|
405
|
+
port_range_str = (CONFIG[:port_range] || "0").to_s
|
406
|
+
raise "Specify a positive integer <=16 for port range" unless port_range_str.match?(/\A\d+\z/) && port_range_str.to_i <= 16
|
407
|
+
port_range_str.to_i
|
408
|
+
end
|
402
409
|
@uuid = nil # for CDP
|
403
410
|
|
404
411
|
super()
|
@@ -452,7 +459,9 @@ module DEBUGGER__
|
|
452
459
|
end
|
453
460
|
end
|
454
461
|
rescue Errno::EADDRINUSE
|
455
|
-
|
462
|
+
number_of_retries = @port_range.zero? ? 10 : @port_range
|
463
|
+
if retry_cnt < number_of_retries
|
464
|
+
@port += 1 unless @port_range.zero?
|
456
465
|
retry_cnt += 1
|
457
466
|
sleep 0.1
|
458
467
|
retry
|
data/lib/debug/server_cdp.rb
CHANGED
data/lib/debug/server_dap.rb
CHANGED
data/lib/debug/session.rb
CHANGED
@@ -931,7 +931,6 @@ module DEBUGGER__
|
|
931
931
|
register_command 'eval', 'call' do |arg|
|
932
932
|
if arg == nil || arg.empty?
|
933
933
|
show_help 'eval'
|
934
|
-
@ui.puts "\nTo evaluate the variable `#{cmd}`, use `pp #{cmd}` instead."
|
935
934
|
:retry
|
936
935
|
else
|
937
936
|
request_eval :call, arg
|
@@ -1144,7 +1143,7 @@ module DEBUGGER__
|
|
1144
1143
|
|
1145
1144
|
def process_command line
|
1146
1145
|
if line.empty?
|
1147
|
-
if @repl_prev_line
|
1146
|
+
if @repl_prev_line && !CONFIG[:no_repeat]
|
1148
1147
|
line = @repl_prev_line
|
1149
1148
|
else
|
1150
1149
|
return :retry
|
@@ -2301,11 +2300,20 @@ module DEBUGGER__
|
|
2301
2300
|
end
|
2302
2301
|
|
2303
2302
|
def self.load_rc
|
2304
|
-
[
|
2305
|
-
|
2306
|
-
|
2307
|
-
|
2308
|
-
|
2303
|
+
rc_file_paths = [
|
2304
|
+
[File.expand_path('~/.rdbgrc'), true],
|
2305
|
+
[File.expand_path('~/.rdbgrc.rb'), true],
|
2306
|
+
# ['./.rdbgrc', true], # disable because of security concern
|
2307
|
+
]
|
2308
|
+
|
2309
|
+
if (xdg_home = ENV["XDG_CONFIG_HOME"])
|
2310
|
+
rc_file_paths << [File.expand_path(File.join(xdg_home, "rdbg", "config")), true]
|
2311
|
+
rc_file_paths << [File.expand_path(File.join(xdg_home, "rdbg", "config.rb")), true]
|
2312
|
+
end
|
2313
|
+
|
2314
|
+
rc_file_paths << [CONFIG[:init_script], false]
|
2315
|
+
|
2316
|
+
rc_file_paths.each{|(path, rc)|
|
2309
2317
|
next unless path
|
2310
2318
|
next if rc && CONFIG[:no_rc] # ignore rc
|
2311
2319
|
|
data/lib/debug/thread_client.rb
CHANGED
@@ -44,7 +44,7 @@ module DEBUGGER__
|
|
44
44
|
end
|
45
45
|
|
46
46
|
module GlobalVariablesHelper
|
47
|
-
SKIP_GLOBAL_LIST = %i[$= $KCODE $-K $SAFE].freeze
|
47
|
+
SKIP_GLOBAL_LIST = %i[$= $KCODE $-K $SAFE $FILENAME].freeze
|
48
48
|
def safe_global_variables
|
49
49
|
global_variables.reject{|name| SKIP_GLOBAL_LIST.include? name }
|
50
50
|
end
|
@@ -350,6 +350,7 @@ module DEBUGGER__
|
|
350
350
|
next if tp.path.start_with?(__dir__)
|
351
351
|
next if tp.path.start_with?('<internal:trace_point>')
|
352
352
|
next unless File.exist?(tp.path) if CONFIG[:skip_nosrc]
|
353
|
+
next if skip_internal_path?(tp.path)
|
353
354
|
loc = caller_locations(1, 1).first
|
354
355
|
next if skip_location?(loc)
|
355
356
|
next if iter && (iter -= 1) > 0
|
@@ -369,6 +370,7 @@ module DEBUGGER__
|
|
369
370
|
next if tp.path.start_with?(__dir__)
|
370
371
|
next if tp.path.start_with?('<internal:trace_point>')
|
371
372
|
next unless File.exist?(tp.path) if CONFIG[:skip_nosrc]
|
373
|
+
next if skip_internal_path?(tp.path)
|
372
374
|
loc = caller_locations(1, 1).first
|
373
375
|
next if skip_location?(loc)
|
374
376
|
next if iter && (iter -= 1) > 0
|
@@ -1079,13 +1081,13 @@ module DEBUGGER__
|
|
1079
1081
|
when :up
|
1080
1082
|
if @current_frame_index + 1 < @target_frames.size
|
1081
1083
|
@current_frame_index += 1
|
1082
|
-
show_src max_lines:
|
1084
|
+
show_src max_lines: CONFIG[:show_src_lines_frame]
|
1083
1085
|
show_frame(@current_frame_index)
|
1084
1086
|
end
|
1085
1087
|
when :down
|
1086
1088
|
if @current_frame_index > 0
|
1087
1089
|
@current_frame_index -= 1
|
1088
|
-
show_src max_lines:
|
1090
|
+
show_src max_lines: CONFIG[:show_src_lines_frame]
|
1089
1091
|
show_frame(@current_frame_index)
|
1090
1092
|
end
|
1091
1093
|
when :set
|
@@ -1097,7 +1099,7 @@ module DEBUGGER__
|
|
1097
1099
|
puts "out of frame index: #{index}"
|
1098
1100
|
end
|
1099
1101
|
end
|
1100
|
-
show_src max_lines:
|
1102
|
+
show_src max_lines: CONFIG[:show_src_lines_frame]
|
1101
1103
|
show_frame(@current_frame_index)
|
1102
1104
|
else
|
1103
1105
|
raise "unsupported frame operation: #{arg.inspect}"
|
data/lib/debug/version.rb
CHANGED