debug 1.6.2 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
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|