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.
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: ['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_evaledsrc: ['RUBY_DEBUG_SHOW_EVALEDSRC', "UI: Show actually evaluated source", :bool, "false"],
18
- show_frames: ['RUBY_DEBUG_SHOW_FRAMES', "UI: Show n frames on breakpoint", :int, "2"],
19
- use_short_path: ['RUBY_DEBUG_USE_SHORT_PATH', "UI: Show shorten PATH (like $(Gem)/foo.rb)", :bool, "false"],
20
- no_color: ['RUBY_DEBUG_NO_COLOR', "UI: Do not use colorize", :bool, "false"],
21
- no_sigint_hook: ['RUBY_DEBUG_NO_SIGINT_HOOK', "UI: Do not suspend on SIGINT", :bool, "false"],
22
- no_reline: ['RUBY_DEBUG_NO_RELINE', "UI: Do not use Reline library", :bool, "false"],
23
- no_hint: ['RUBY_DEBUG_NO_HINT', "UI: Do not show the hint on the REPL", :bool, "false"],
24
- no_lineno: ['RUBY_DEBUG_NO_LINENO', "UI: Do not show line numbers", :bool, "false"],
25
- irb_console: ["RUBY_DEBUG_IRB_CONSOLE", "UI: Use IRB as the console", :bool, "false"],
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: ['RUBY_DEBUG_SKIP_PATH', "CONTROL: Skip showing/entering frames for given paths", :path],
29
- skip_nosrc: ['RUBY_DEBUG_SKIP_NOSRC', "CONTROL: Skip on no source code lines", :bool, "false"],
30
- keep_alloc_site:['RUBY_DEBUG_KEEP_ALLOC_SITE',"CONTROL: Keep allocation site and p, pp shows it", :bool, "false"],
31
- postmortem: ['RUBY_DEBUG_POSTMORTEM', "CONTROL: Enable postmortem debug", :bool, "false"],
32
- fork_mode: ['RUBY_DEBUG_FORK_MODE', "CONTROL: Control which process activates a debugger after fork (both/parent/child)", :forkmode, "both"],
33
- sigdump_sig: ['RUBY_DEBUG_SIGDUMP_SIG', "CONTROL: Sigdump signal", :bool, "false"],
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: ['RUBY_DEBUG_NONSTOP', "BOOT: Nonstop mode", :bool, "false"],
37
- stop_at_load: ['RUBY_DEBUG_STOP_AT_LOAD',"BOOT: Stop at just loading location", :bool, "false"],
38
- init_script: ['RUBY_DEBUG_INIT_SCRIPT', "BOOT: debug command script path loaded at first stop"],
39
- commands: ['RUBY_DEBUG_COMMANDS', "BOOT: debug commands invoked at first stop. Commands should be separated by `;;`"],
40
- no_rc: ['RUBY_DEBUG_NO_RC', "BOOT: ignore loading ~/.rdbgrc(.rb)", :bool, "false"],
41
- history_file: ['RUBY_DEBUG_HISTORY_FILE',"BOOT: history file", :string, "~/.rdbg_history"],
42
- save_history: ['RUBY_DEBUG_SAVE_HISTORY',"BOOT: maximum save history lines", :int, "10000"],
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: ['RUBY_DEBUG_OPEN', "REMOTE: Open remote port (same as `rdbg --open` option)"],
46
- port: ['RUBY_DEBUG_PORT', "REMOTE: TCP/IP remote debugging: port"],
47
- host: ['RUBY_DEBUG_HOST', "REMOTE: TCP/IP remote debugging: host", :string, "127.0.0.1"],
48
- sock_path: ['RUBY_DEBUG_SOCK_PATH', "REMOTE: UNIX Domain Socket remote debugging: socket path"],
49
- sock_dir: ['RUBY_DEBUG_SOCK_DIR', "REMOTE: UNIX Domain Socket remote debugging: socket directory"],
50
- local_fs_map: ['RUBY_DEBUG_LOCAL_FS_MAP', "REMOTE: Specify local fs map", :path_map],
51
- skip_bp: ['RUBY_DEBUG_SKIP_BP', "REMOTE: Skip breakpoints if no clients are attached", :bool, 'false'],
52
- cookie: ['RUBY_DEBUG_COOKIE', "REMOTE: Cookie for negotiation"],
53
- session_name: ['RUBY_DEBUG_SESSION_NAME', "REMOTE: Session name for differentiating multiple sessions"],
54
- 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))"],
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: ['RUBY_DEBUG_PARENT_ON_FORK', "OBSOLETE: Keep debugging parent process on fork", :bool, "false"],
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
- history_file = CONFIG[:history_file]
157
-
158
- if !history_file.empty?
159
- File.expand_path(history_file)
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
- history_file
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
- ["#{FH}#{f}".dup] + File.readlines(path)
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
- if !line.start_with?(FH) && !line.strip.empty?
197
- f.puts line.strip
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?
@@ -86,7 +86,9 @@ module DEBUGGER__
86
86
 
87
87
  def block_identifier
88
88
  return unless frame_type == :block
89
- _, level, block_loc = location.label.match(BLOCK_LABL_REGEXP).to_a
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
- if retry_cnt < 10
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
@@ -688,7 +688,7 @@ module DEBUGGER__
688
688
  yield $stderr
689
689
  end
690
690
 
691
- def puts result=''
691
+ def puts result = ""
692
692
  # STDERR.puts "puts: #{result}"
693
693
  # send_event 'output', category: 'stderr', output: "PUTS!!: " + result.to_s
694
694
  end
@@ -501,7 +501,7 @@ module DEBUGGER__
501
501
  send_response(req, **res)
502
502
  end
503
503
 
504
- def puts result
504
+ def puts result = ""
505
505
  # STDERR.puts "puts: #{result}"
506
506
  send_event 'output', category: 'console', output: "#{result&.chomp}\n"
507
507
  end
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
- [[File.expand_path('~/.rdbgrc'), true],
2305
- [File.expand_path('~/.rdbgrc.rb'), true],
2306
- # ['./.rdbgrc', true], # disable because of security concern
2307
- [CONFIG[:init_script], false],
2308
- ].each{|(path, rc)|
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
 
@@ -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: 1
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: 1
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: 1
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DEBUGGER__
4
- VERSION = "1.9.2"
4
+ VERSION = "1.11.0"
5
5
  end