debug 1.10.0 → 1.11.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/README.md +119 -93
- data/ext/debug/iseq_collector.c +1 -1
- data/lib/debug/breakpoint.rb +2 -2
- data/lib/debug/config.rb +38 -36
- data/lib/debug/console.rb +23 -11
- data/lib/debug/frame_info.rb +4 -2
- data/lib/debug/server.rb +1 -0
- 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 +116 -92
- metadata +4 -5
data/lib/debug/config.rb
CHANGED
|
@@ -12,50 +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
|
-
port_range:
|
|
48
|
-
host:
|
|
49
|
-
sock_path:
|
|
50
|
-
sock_dir:
|
|
51
|
-
local_fs_map:
|
|
52
|
-
skip_bp:
|
|
53
|
-
cookie:
|
|
54
|
-
session_name:
|
|
55
|
-
chrome_path:
|
|
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))"],
|
|
56
58
|
|
|
57
59
|
# obsolete
|
|
58
|
-
parent_on_fork:
|
|
60
|
+
parent_on_fork: ['RUBY_DEBUG_PARENT_ON_FORK', "OBSOLETE: Keep debugging parent process on fork", :bool, "false"],
|
|
59
61
|
}.freeze
|
|
60
62
|
|
|
61
63
|
CONFIG_MAP = CONFIG_SET.map{|k, (ev, _)| [k, ev]}.to_h.freeze
|
data/lib/debug/console.rb
CHANGED
|
@@ -153,21 +153,29 @@ 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
|
+
require 'fileutils'
|
|
167
|
+
FileUtils.mkdir_p(File.dirname(path)) unless File.exist?(path)
|
|
168
|
+
path
|
|
163
169
|
end
|
|
164
170
|
|
|
165
171
|
FH = "# Today's OMIKUJI: "
|
|
166
172
|
|
|
167
173
|
def read_history_file
|
|
168
|
-
if history && File.exist?(path = history_file)
|
|
174
|
+
if history && File.exist?(path = history_file())
|
|
169
175
|
f = (['', 'DAI-', 'CHU-', 'SHO-'].map{|e| e+'KICHI'}+['KYO']).sample
|
|
170
|
-
|
|
176
|
+
# Read history file and scrub invalid characters to prevent encoding errors
|
|
177
|
+
lines = File.readlines(path).map(&:scrub)
|
|
178
|
+
["#{FH}#{f}".dup] + lines
|
|
171
179
|
else
|
|
172
180
|
[]
|
|
173
181
|
end
|
|
@@ -186,15 +194,17 @@ module DEBUGGER__
|
|
|
186
194
|
def deactivate
|
|
187
195
|
if history && @init_history_lines
|
|
188
196
|
added_records = history.to_a[@init_history_lines .. -1]
|
|
189
|
-
path = history_file
|
|
197
|
+
path = history_file()
|
|
190
198
|
max = CONFIG[:save_history]
|
|
191
199
|
|
|
192
200
|
if !added_records.empty? && !path.empty?
|
|
193
201
|
orig_records = read_history_file
|
|
194
|
-
open(history_file, 'w'){|f|
|
|
202
|
+
open(history_file(), 'w'){|f|
|
|
195
203
|
(orig_records + added_records).last(max).each{|line|
|
|
196
|
-
|
|
197
|
-
|
|
204
|
+
# Use scrub to handle encoding issues gracefully
|
|
205
|
+
scrubbed_line = line.scrub.strip
|
|
206
|
+
if !line.start_with?(FH) && !scrubbed_line.empty?
|
|
207
|
+
f.puts scrubbed_line
|
|
198
208
|
end
|
|
199
209
|
}
|
|
200
210
|
}
|
|
@@ -204,6 +214,8 @@ module DEBUGGER__
|
|
|
204
214
|
|
|
205
215
|
def load_history
|
|
206
216
|
read_history_file.each{|line|
|
|
217
|
+
# Use scrub to handle encoding issues gracefully, then strip
|
|
218
|
+
line.scrub!
|
|
207
219
|
line.strip!
|
|
208
220
|
history << line unless line.empty?
|
|
209
221
|
} 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
|
|
|
@@ -169,7 +171,7 @@ module DEBUGGER__
|
|
|
169
171
|
|
|
170
172
|
private def get_singleton_class obj
|
|
171
173
|
obj.singleton_class # TODO: don't use it
|
|
172
|
-
rescue
|
|
174
|
+
rescue Exception
|
|
173
175
|
nil
|
|
174
176
|
end
|
|
175
177
|
|
data/lib/debug/server.rb
CHANGED
data/lib/debug/server_dap.rb
CHANGED
|
@@ -358,7 +358,7 @@ module DEBUGGER__
|
|
|
358
358
|
}
|
|
359
359
|
send_response req, breakpoints: (bps.map do |bp| {verified: true,} end)
|
|
360
360
|
else
|
|
361
|
-
send_response req,
|
|
361
|
+
send_response req, breakpoints: (args['breakpoints'].map do |bp| {verified: false, message: "#{req_path} could not be located; specify source location in launch.json with \"localfsMap\" or \"localfs\""} end)
|
|
362
362
|
end
|
|
363
363
|
|
|
364
364
|
when 'setFunctionBreakpoints'
|
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
|
@@ -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}"
|
|
@@ -1308,7 +1310,7 @@ module DEBUGGER__
|
|
|
1308
1310
|
frame._local_variables = b.local_variables.map{|name|
|
|
1309
1311
|
[name, b.local_variable_get(name)]
|
|
1310
1312
|
}.to_h
|
|
1311
|
-
frame._callee = b.eval('__callee__')
|
|
1313
|
+
frame._callee = b.eval('::Kernel.__callee__')
|
|
1312
1314
|
end
|
|
1313
1315
|
}
|
|
1314
1316
|
append(frames)
|
data/lib/debug/version.rb
CHANGED