debug 1.6.2 → 1.7.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.
data/lib/debug/config.rb CHANGED
@@ -14,6 +14,7 @@ module DEBUGGER__
14
14
  # UI setting
15
15
  log_level: ['RUBY_DEBUG_LOG_LEVEL', "UI: Log level same as Logger", :loglevel, "WARN"],
16
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"],
17
18
  show_frames: ['RUBY_DEBUG_SHOW_FRAMES', "UI: Show n frames on breakpoint", :int, "2"],
18
19
  use_short_path: ['RUBY_DEBUG_USE_SHORT_PATH', "UI: Show shorten PATH (like $(Gem)/foo.rb)", :bool, "false"],
19
20
  no_color: ['RUBY_DEBUG_NO_COLOR', "UI: Do not use colorize", :bool, "false"],
@@ -33,12 +34,13 @@ module DEBUGGER__
33
34
  nonstop: ['RUBY_DEBUG_NONSTOP', "BOOT: Nonstop mode", :bool, "false"],
34
35
  stop_at_load: ['RUBY_DEBUG_STOP_AT_LOAD',"BOOT: Stop at just loading location", :bool, "false"],
35
36
  init_script: ['RUBY_DEBUG_INIT_SCRIPT', "BOOT: debug command script path loaded at first stop"],
36
- commands: ['RUBY_DEBUG_COMMANDS', "BOOT: debug commands invoked at first stop. commands should be separated by ';;'"],
37
+ commands: ['RUBY_DEBUG_COMMANDS', "BOOT: debug commands invoked at first stop. Commands should be separated by `;;`"],
37
38
  no_rc: ['RUBY_DEBUG_NO_RC', "BOOT: ignore loading ~/.rdbgrc(.rb)", :bool, "false"],
38
39
  history_file: ['RUBY_DEBUG_HISTORY_FILE',"BOOT: history file", :string, "~/.rdbg_history"],
39
40
  save_history: ['RUBY_DEBUG_SAVE_HISTORY',"BOOT: maximum save history lines", :int, "10000"],
40
41
 
41
42
  # remote setting
43
+ open: ['RUBY_DEBUG_OPEN', "REMOTE: Open remote port (same as `rdbg --open` option)"],
42
44
  port: ['RUBY_DEBUG_PORT', "REMOTE: TCP/IP remote debugging: port"],
43
45
  host: ['RUBY_DEBUG_HOST', "REMOTE: TCP/IP remote debugging: host", :string, "127.0.0.1"],
44
46
  sock_path: ['RUBY_DEBUG_SOCK_PATH', "REMOTE: UNIX Domain Socket remote debugging: socket path"],
@@ -46,7 +48,6 @@ module DEBUGGER__
46
48
  local_fs_map: ['RUBY_DEBUG_LOCAL_FS_MAP', "REMOTE: Specify local fs map", :path_map],
47
49
  skip_bp: ['RUBY_DEBUG_SKIP_BP', "REMOTE: Skip breakpoints if no clients are attached", :bool, 'false'],
48
50
  cookie: ['RUBY_DEBUG_COOKIE', "REMOTE: Cookie for negotiation"],
49
- open_frontend: ['RUBY_DEBUG_OPEN_FRONTEND',"REMOTE: frontend used by open command (vscode, chrome, default: rdbg)."],
50
51
  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))"],
51
52
 
52
53
  # obsolete
@@ -63,8 +64,6 @@ module DEBUGGER__
63
64
  end
64
65
 
65
66
  def initialize argv
66
- @skip_all = false
67
-
68
67
  if self.class.config
69
68
  raise 'Can not make multiple configurations in one process'
70
69
  end
@@ -94,14 +93,6 @@ module DEBUGGER__
94
93
  set_config(key => val)
95
94
  end
96
95
 
97
- def skip_all
98
- @skip_all = true
99
- end
100
-
101
- def skip?
102
- @skip_all
103
- end
104
-
105
96
  def set_config(**kw)
106
97
  conf = config.dup
107
98
  kw.each{|k, v|
@@ -158,6 +149,12 @@ module DEBUGGER__
158
149
  if_updated old_conf, conf, :sigdump_sig do |old_sig, new_sig|
159
150
  setup_sigdump old_sig, new_sig
160
151
  end
152
+
153
+ if_updated old_conf, conf, :no_sigint_hook do |old, new|
154
+ if defined?(SESSION)
155
+ SESSION.set_no_sigint_hook old, new
156
+ end
157
+ end
161
158
  end
162
159
 
163
160
  private def if_updated old_conf, new_conf, key
@@ -308,8 +305,25 @@ module DEBUGGER__
308
305
  'If TCP/IP options are not given, a UNIX domain socket will be used.',
309
306
  'If FRONTEND is given, prepare for the FRONTEND.',
310
307
  'Now rdbg, vscode and chrome is supported.') do |f|
311
- config[:remote] = true
312
- config[:open_frontend] = f.downcase if f
308
+
309
+ case f # some format patterns are not documented yet
310
+ when nil
311
+ config[:open] = true
312
+ when /\A\d\z/
313
+ config[:open] = true
314
+ config[:port] = f.to_i
315
+ when /\A(\S+):(\d+)\z/
316
+ config[:open] = true
317
+ config[:host] = $1
318
+ config[:port] = $2.to_i
319
+ when 'tcp'
320
+ config[:open] = true
321
+ config[:port] ||= 0
322
+ when 'vscode', 'chrome', 'cdp'
323
+ config[:open] = f&.downcase
324
+ else
325
+ raise "Unknown option for --open: #{f}"
326
+ end
313
327
  end
314
328
  o.on('--sock-path=SOCK_PATH', 'UNIX Domain socket path') do |path|
315
329
  config[:sock_path] = path
@@ -479,10 +493,14 @@ module DEBUGGER__
479
493
  when /\A\s*### (.+)/
480
494
  cat = $1
481
495
  break if $1 == 'END'
482
- when /\A when (.+)/
496
+ when /\A register_command (.+)/
483
497
  next unless cat
484
498
  next unless desc
485
- ws = $1.split(/,\s*/).map{|e| e.gsub('\'', '')}
499
+
500
+ ws = []
501
+ $1.gsub(/'([a-z]+)'/){|w|
502
+ ws << $1
503
+ }
486
504
  helps[cat] << [ws, desc]
487
505
  desc = nil
488
506
  max_w = ws.max_by{|w| w.length}
data/lib/debug/console.rb CHANGED
File without changes
File without changes
data/lib/debug/local.rb CHANGED
@@ -13,23 +13,28 @@ module DEBUGGER__
13
13
  false
14
14
  end
15
15
 
16
- def activate session, on_fork: false
17
- unless CONFIG[:no_sigint_hook]
18
- prev_handler = trap(:SIGINT){
19
- if session.active?
20
- ThreadClient.current.on_trap :SIGINT
21
- end
22
- }
23
- session.intercept_trap_sigint_start prev_handler
24
- end
16
+ def activate_sigint
17
+ prev_handler = trap(:SIGINT){
18
+ if SESSION.active?
19
+ ThreadClient.current.on_trap :SIGINT
20
+ end
21
+ }
22
+ SESSION.intercept_trap_sigint_start prev_handler
25
23
  end
26
24
 
27
- def deactivate
25
+ def deactivate_sigint
28
26
  if SESSION.intercept_trap_sigint?
29
27
  prev = SESSION.intercept_trap_sigint_end
30
28
  trap(:SIGINT, prev)
31
29
  end
30
+ end
31
+
32
+ def activate session, on_fork: false
33
+ activate_sigint unless CONFIG[:no_sigint_hook]
34
+ end
32
35
 
36
+ def deactivate
37
+ deactivate_sigint
33
38
  @console.deactivate
34
39
  end
35
40
 
@@ -42,6 +47,7 @@ module DEBUGGER__
42
47
  end
43
48
 
44
49
  def quit n
50
+ yield
45
51
  exit n
46
52
  end
47
53
 
data/lib/debug/open.rb CHANGED
File without changes
File without changes
data/lib/debug/prelude.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  return if ENV['RUBY_DEBUG_ENABLE'] == '0'
4
- return if defined?(::DEBUGGER__)
4
+ return if defined?(::DEBUGGER__::Session)
5
5
 
6
6
  # Put the following line in your login script (e.g. ~/.bash_profile) with modified path:
7
7
  #
data/lib/debug/server.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'socket'
4
- require 'etc'
5
4
  require_relative 'config'
6
5
  require_relative 'version'
7
6
 
@@ -22,6 +21,7 @@ module DEBUGGER__
22
21
 
23
22
  class Terminate < StandardError; end
24
23
  class GreetingError < StandardError; end
24
+ class RetryConnection < StandardError; end
25
25
 
26
26
  def deactivate
27
27
  @reader_thread.raise Terminate
@@ -78,6 +78,8 @@ module DEBUGGER__
78
78
  next
79
79
  rescue Terminate
80
80
  raise # should catch at outer scope
81
+ rescue RetryConnection
82
+ next
81
83
  rescue => e
82
84
  DEBUGGER__.warn "ReaderThreadError: #{e}"
83
85
  pp e.backtrace
@@ -128,6 +130,8 @@ module DEBUGGER__
128
130
  def greeting
129
131
  case g = @sock.gets
130
132
  when /^info cookie:\s+(.*)$/
133
+ require 'etc'
134
+
131
135
  check_cookie $1
132
136
  @sock.puts "PID: #{Process.pid}, $0: #{$0}"
133
137
  @sock.puts "debug #{VERSION} on #{RUBY_DESCRIPTION}"
@@ -140,7 +144,8 @@ module DEBUGGER__
140
144
 
141
145
  # TODO: protocol version
142
146
  if v != VERSION
143
- raise GreetingError, "Incompatible version (server:#{VERSION} and client:#{$1})"
147
+ @sock.puts msg = "out DEBUGGER: Incompatible version (server:#{VERSION} and client:#{$1})"
148
+ raise GreetingError, msg
144
149
  end
145
150
  parse_option(params)
146
151
 
@@ -157,16 +162,13 @@ module DEBUGGER__
157
162
  @need_pause_at_first = false
158
163
  dap_setup @sock.read($1.to_i)
159
164
 
160
- when /^GET \/.* HTTP\/1.1/
165
+ when /^GET\s\/json\sHTTP\/1.1/, /^GET\s\/json\/version\sHTTP\/1.1/, /^GET\s\/\w{8}-\w{4}-\w{4}-\w{4}-\w{12}\sHTTP\/1.1/
166
+ # The reason for not using @uuid here is @uuid is nil if users run debugger without `--open=chrome`.
167
+
161
168
  require_relative 'server_cdp'
162
169
 
163
170
  self.extend(UI_CDP)
164
- @repl = false
165
- @need_pause_at_first = false
166
- CONFIG.set_config no_color: true
167
-
168
- @ws_server = UI_CDP::WebSocketServer.new(@sock)
169
- @ws_server.handshake
171
+ send_chrome_response g
170
172
  else
171
173
  raise GreetingError, "Unknown greeting message: #{g}"
172
174
  end
@@ -174,17 +176,17 @@ module DEBUGGER__
174
176
 
175
177
  def process
176
178
  while true
177
- DEBUGGER__.info "sleep IO.select"
178
- r = IO.select([@sock])
179
- DEBUGGER__.info "wakeup IO.select"
179
+ DEBUGGER__.debug{ "sleep IO.select" }
180
+ _r = IO.select([@sock])
181
+ DEBUGGER__.debug{ "wakeup IO.select" }
180
182
 
181
183
  line = @session.process_group.sync do
182
184
  unless IO.select([@sock], nil, nil, 0)
183
- DEBUGGER__.info "UI_Server can not read"
185
+ DEBUGGER__.debug{ "UI_Server can not read" }
184
186
  break :can_not_read
185
187
  end
186
188
  @sock.gets&.chomp.tap{|line|
187
- DEBUGGER__.info "UI_Server received: #{line}"
189
+ DEBUGGER__.debug{ "UI_Server received: #{line}" }
188
190
  }
189
191
  end
190
192
 
@@ -340,12 +342,12 @@ module DEBUGGER__
340
342
  if @repl
341
343
  raise "not in subsession, but received: #{line.inspect}" unless @session.in_subsession?
342
344
  line = "input #{Process.pid}"
343
- DEBUGGER__.info "send: #{line}"
345
+ DEBUGGER__.debug{ "send: #{line}" }
344
346
  s.puts line
345
347
  end
346
348
  sleep 0.01 until @q_msg
347
349
  @q_msg.pop.tap{|msg|
348
- DEBUGGER__.info "readline: #{msg.inspect}"
350
+ DEBUGGER__.debug{ "readline: #{msg.inspect}" }
349
351
  }
350
352
  end || 'continue')
351
353
 
@@ -361,7 +363,7 @@ module DEBUGGER__
361
363
  Process.kill(TRAP_SIGNAL, Process.pid)
362
364
  end
363
365
 
364
- def quit n
366
+ def quit n, &_b
365
367
  # ignore n
366
368
  sock do |s|
367
369
  s.puts "quit"
@@ -395,6 +397,7 @@ module DEBUGGER__
395
397
  raise "Specify digits for port number"
396
398
  end
397
399
  end
400
+ @uuid = nil # for CDP
398
401
 
399
402
  super()
400
403
  end
@@ -402,11 +405,12 @@ module DEBUGGER__
402
405
  def chrome_setup
403
406
  require_relative 'server_cdp'
404
407
 
405
- unless @chrome_pid = UI_CDP.setup_chrome(@local_addr.inspect_sockaddr)
408
+ @uuid = SecureRandom.uuid
409
+ unless @chrome_pid = UI_CDP.setup_chrome(@local_addr.inspect_sockaddr, @uuid)
406
410
  DEBUGGER__.warn <<~EOS
407
411
  With Chrome browser, type the following URL in the address-bar:
408
412
 
409
- devtools://devtools/bundled/inspector.html?v8only=true&panel=sources&ws=#{@local_addr.inspect_sockaddr}/#{SecureRandom.uuid}
413
+ devtools://devtools/bundled/inspector.html?v8only=true&panel=sources&ws=#{@local_addr.inspect_sockaddr}/#{@uuid}
410
414
 
411
415
  EOS
412
416
  end
@@ -434,7 +438,7 @@ module DEBUGGER__
434
438
  #
435
439
  EOS
436
440
 
437
- case CONFIG[:open_frontend]
441
+ case CONFIG[:open]
438
442
  when 'chrome'
439
443
  chrome_setup
440
444
  when 'vscode'
@@ -491,7 +495,7 @@ module DEBUGGER__
491
495
  end
492
496
 
493
497
  ::DEBUGGER__.warn "Debugger can attach via UNIX domain socket (#{@sock_path})"
494
- vscode_setup @sock_path if CONFIG[:open_frontend] == 'vscode'
498
+ vscode_setup @sock_path if CONFIG[:open] == 'vscode'
495
499
 
496
500
  begin
497
501
  Socket.unix_server_loop @sock_path do |sock, client|