debug 1.3.4 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,10 +2,11 @@
2
2
 
3
3
  module DEBUGGER__
4
4
  FrameInfo = Struct.new(:location, :self, :binding, :iseq, :class, :frame_depth,
5
- :has_return_value, :return_value,
5
+ :has_return_value, :return_value,
6
6
  :has_raised_exception, :raised_exception,
7
7
  :show_line,
8
- :_local_variables, :_callee # for recorder
8
+ :_local_variables, :_callee, # for recorder
9
+ :dupped_binding,
9
10
  )
10
11
 
11
12
  # extend FrameInfo with debug.so
@@ -31,7 +32,7 @@ module DEBUGGER__
31
32
  use_short_path = CONFIG[:use_short_path]
32
33
 
33
34
  case
34
- when use_short_path && path.start_with?(dir = CONFIG["rubylibdir"] + '/')
35
+ when use_short_path && path.start_with?(dir = RbConfig::CONFIG["rubylibdir"] + '/')
35
36
  path.sub(dir, '$(rubylibdir)/')
36
37
  when use_short_path && Gem.path.any? do |gp|
37
38
  path.start_with?(dir = gp + '/gems/')
@@ -110,7 +111,7 @@ module DEBUGGER__
110
111
 
111
112
  def return_str
112
113
  if self.binding && iseq && has_return_value
113
- DEBUGGER__.short_inspect(return_value)
114
+ DEBUGGER__.safe_inspect(return_value, short: true)
114
115
  end
115
116
  end
116
117
 
@@ -118,19 +119,13 @@ module DEBUGGER__
118
119
  "#{pretty_path}:#{location.lineno}"
119
120
  end
120
121
 
121
- private def make_binding
122
- __newb__ = self.self.instance_eval('binding')
123
- self.local_variables.each{|var, val|
124
- __newb__.local_variable_set(var, val)
125
- }
126
- __newb__
127
- end
128
-
129
122
  def eval_binding
130
- if b = self.binding
123
+ if b = self.dupped_binding
131
124
  b
132
- elsif self.local_variables
133
- make_binding
125
+ else
126
+ b = TOPLEVEL_BINDING unless b = self.binding
127
+ b = self.binding || TOPLEVEL_BINDING
128
+ self.dupped_binding = b.dup
134
129
  end
135
130
  end
136
131
 
@@ -160,7 +155,7 @@ module DEBUGGER__
160
155
  vars = iseq.locals[0...argc]
161
156
  vars.map{|var|
162
157
  begin
163
- { name: var, value: DEBUGGER__.short_inspect(local_variable_get(var)) }
158
+ { name: var, value: DEBUGGER__.safe_inspect(local_variable_get(var), short: true) }
164
159
  rescue NameError, TypeError
165
160
  nil
166
161
  end
data/lib/debug/prelude.rb CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  return if defined?(::DEBUGGER__)
4
4
 
5
+ # Put the following line in your login script (e.g. ~/.bash_profile) with modified path:
5
6
  #
6
- # put the following line in .bash_profile
7
- # export RUBYOPT="-r .../debug/prelude $(RUBYOPT)"
7
+ # export RUBYOPT="-r /path/to/debug/prelude $(RUBYOPT)"
8
8
  #
9
9
  module Kernel
10
10
  def debugger(*a, up_level: 0, **kw)
data/lib/debug/server.rb CHANGED
@@ -75,12 +75,7 @@ module DEBUGGER__
75
75
  DEBUGGER__.warn "ReaderThreadError: #{e}"
76
76
  pp e.backtrace
77
77
  ensure
78
- DEBUGGER__.warn "Disconnected."
79
- @sock = nil
80
- @q_msg.close
81
- @q_msg = nil
82
- @q_ans.close
83
- @q_ans = nil
78
+ cleanup_reader
84
79
  end # accept
85
80
 
86
81
  rescue Terminate
@@ -88,6 +83,15 @@ module DEBUGGER__
88
83
  end
89
84
  end
90
85
 
86
+ def cleanup_reader
87
+ DEBUGGER__.warn "Disconnected."
88
+ @sock = nil
89
+ @q_msg.close
90
+ @q_msg = nil
91
+ @q_ans.close
92
+ @q_ans = nil
93
+ end
94
+
91
95
  def greeting
92
96
  case g = @sock.gets
93
97
  when /^version:\s+(.+)\s+width: (\d+) cookie:\s+(.*)$/
@@ -118,8 +122,8 @@ module DEBUGGER__
118
122
  @repl = false
119
123
  CONFIG.set_config no_color: true
120
124
 
121
- @web_sock = UI_CDP::WebSocket.new(@sock)
122
- @web_sock.handshake
125
+ @ws_server = UI_CDP::WebSocketServer.new(@sock)
126
+ @ws_server.handshake
123
127
  else
124
128
  raise "Greeting message error: #{g}"
125
129
  end
@@ -180,7 +184,7 @@ module DEBUGGER__
180
184
 
181
185
  def sigurg_overridden? prev_handler
182
186
  case prev_handler
183
- when "SYSTEM_DEFAULT"
187
+ when "SYSTEM_DEFAULT", "DEFAULT"
184
188
  false
185
189
  when Proc
186
190
  if prev_handler.source_location[0] == __FILE__
@@ -193,10 +197,19 @@ module DEBUGGER__
193
197
  end
194
198
  end
195
199
 
200
+ begin
201
+ prev = trap(:SIGURG, nil)
202
+ trap(:SIGURG, prev)
203
+ TRAP_SIGNAL = :SIGURG
204
+ rescue ArgumentError
205
+ # maybe Windows?
206
+ TRAP_SIGNAL = :SIGINT
207
+ end
208
+
196
209
  def setup_interrupt
197
- prev_handler = trap(:SIGURG) do
210
+ prev_handler = trap(TRAP_SIGNAL) do
198
211
  # $stderr.puts "trapped SIGINT"
199
- ThreadClient.current.on_trap :SIGURG
212
+ ThreadClient.current.on_trap TRAP_SIGNAL
200
213
 
201
214
  case prev_handler
202
215
  when Proc
@@ -211,7 +224,7 @@ module DEBUGGER__
211
224
  end
212
225
  yield
213
226
  ensure
214
- trap(:SIGURG, prev_handler)
227
+ trap(TRAP_SIGNAL, prev_handler)
215
228
  end
216
229
 
217
230
  attr_reader :reader_thread
@@ -299,7 +312,7 @@ module DEBUGGER__
299
312
 
300
313
  def pause
301
314
  # $stderr.puts "DEBUG: pause request"
302
- Process.kill(:SIGURG, Process.pid)
315
+ Process.kill(TRAP_SIGNAL, Process.pid)
303
316
  end
304
317
 
305
318
  def quit n
@@ -330,29 +343,37 @@ module DEBUGGER__
330
343
  super()
331
344
  end
332
345
 
346
+ def chrome_setup
347
+ require_relative 'server_cdp'
348
+
349
+ unless @chrome_pid = UI_CDP.setup_chrome(@addr)
350
+ DEBUGGER__.warn <<~EOS if CONFIG[:open_frontend] == 'chrome'
351
+ With Chrome browser, type the following URL in the address-bar:
352
+
353
+ devtools://devtools/bundled/inspector.html?ws=#{@addr}
354
+
355
+ EOS
356
+ end
357
+ end
358
+
333
359
  def accept
334
360
  retry_cnt = 0
335
361
  super # for fork
336
362
 
337
363
  begin
338
364
  Socket.tcp_server_sockets @host, @port do |socks|
339
- addr = socks[0].local_address.inspect_sockaddr # Change this part if `socks` are multiple.
365
+ @addr = socks[0].local_address.inspect_sockaddr # Change this part if `socks` are multiple.
340
366
  rdbg = File.expand_path('../../exe/rdbg', __dir__)
341
367
 
342
- DEBUGGER__.warn "Debugger can attach via TCP/IP (#{addr})"
368
+ DEBUGGER__.warn "Debugger can attach via TCP/IP (#{@addr})"
343
369
  DEBUGGER__.info <<~EOS
344
370
  With rdbg, use the following command line:
345
371
  #
346
- # #{rdbg} --attach #{addr.split(':').join(' ')}
372
+ # #{rdbg} --attach #{@addr.split(':').join(' ')}
347
373
  #
348
374
  EOS
349
375
 
350
- DEBUGGER__.warn <<~EOS if CONFIG[:open_frontend] == 'chrome'
351
- With Chrome browser, type the following URL in the address-bar:
352
-
353
- devtools://devtools/bundled/inspector.html?ws=#{addr}
354
-
355
- EOS
376
+ chrome_setup if CONFIG[:open_frontend] == 'chrome'
356
377
 
357
378
  Socket.accept_loop(socks) do |sock, client|
358
379
  @client_addr = client
@@ -389,61 +410,8 @@ module DEBUGGER__
389
410
  end
390
411
 
391
412
  def vscode_setup
392
- require 'tmpdir'
393
- require 'json'
394
- require 'fileutils'
395
-
396
- dir = Dir.mktmpdir("ruby-debug-vscode-")
397
- at_exit{
398
- FileUtils.rm_rf dir
399
- }
400
- Dir.chdir(dir) do
401
- Dir.mkdir('.vscode')
402
- open('README.rb', 'w'){|f|
403
- f.puts <<~MSG
404
- # Wait for starting the attaching to the Ruby process
405
- # This file will be removed at the end of the debuggee process.
406
- #
407
- # Note that vscode-rdbg extension is needed. Please install if you don't have.
408
- MSG
409
- }
410
- open('.vscode/launch.json', 'w'){|f|
411
- f.puts JSON.pretty_generate({
412
- version: '0.2.0',
413
- configurations: [
414
- {
415
- type: "rdbg",
416
- name: "Attach with rdbg",
417
- request: "attach",
418
- rdbgPath: File.expand_path('../../exe/rdbg', __dir__),
419
- debugPort: @sock_path,
420
- autoAttach: true,
421
- }
422
- ]
423
- })
424
- }
425
- end
426
-
427
- cmds = ['code', "#{dir}/", "#{dir}/README.rb"]
428
- cmdline = cmds.join(' ')
429
- ssh_cmdline = "code --remote ssh-remote+[SSH hostname] #{dir}/ #{dir}/README.rb"
430
-
431
- STDERR.puts "Launching: #{cmdline}"
432
- env = ENV.delete_if{|k, h| /RUBY/ =~ k}.to_h
433
-
434
- unless system(env, *cmds)
435
- DEBUGGER__.warn <<~MESSAGE
436
- Can not invoke the command.
437
- Use the command-line on your terminal (with modification if you need).
438
-
439
- #{cmdline}
440
-
441
- If your application is running on a SSH remote host, please try:
442
-
443
- #{ssh_cmdline}
444
-
445
- MESSAGE
446
- end
413
+ require_relative 'server_dap'
414
+ UI_DAP.setup @sock_path
447
415
  end
448
416
 
449
417
  def accept