debug 1.3.1 → 1.4.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/console.rb CHANGED
@@ -34,6 +34,12 @@ module DEBUGGER__
34
34
  load_history_if_not_loaded
35
35
  commands = DEBUGGER__.commands
36
36
 
37
+ prev_completion_proc = Reline.completion_proc
38
+ prev_output_modifier_proc = Reline.output_modifier_proc
39
+ prev_prompt_proc = Reline.prompt_proc
40
+
41
+ Reline.prompt_proc = nil
42
+
37
43
  Reline.completion_proc = -> given do
38
44
  buff = Reline.line_buffer
39
45
  Reline.completion_append_character= ' '
@@ -72,6 +78,13 @@ module DEBUGGER__
72
78
  colorize_code(buff.chomp) + colorize(" # ruby", [:DIM])
73
79
  end
74
80
  end
81
+
82
+ yield
83
+
84
+ ensure
85
+ Reline.completion_proc = prev_completion_proc
86
+ Reline.output_modifier_proc = prev_output_modifier_proc
87
+ Reline.prompt_proc = prev_prompt_proc
75
88
  end
76
89
 
77
90
  private def get_command line
@@ -84,8 +97,9 @@ module DEBUGGER__
84
97
  end
85
98
 
86
99
  def readline prompt
87
- readline_setup prompt
88
- Reline.readmultiline(prompt, true){ true }
100
+ readline_setup prompt do
101
+ Reline.readmultiline(prompt, true){ true }
102
+ end
89
103
  end
90
104
 
91
105
  def history
@@ -145,7 +159,7 @@ module DEBUGGER__
145
159
  FH = "# Today's OMIKUJI: "
146
160
 
147
161
  def read_history_file
148
- if history && File.exists?(path = history_file)
162
+ if history && File.exist?(path = history_file)
149
163
  f = (['', 'DAI-', 'CHU-', 'SHO-'].map{|e| e+'KICHI'}+['KYO']).sample
150
164
  ["#{FH}#{f}".dup] + File.readlines(path)
151
165
  else
@@ -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+(.*)$/
@@ -116,8 +120,10 @@ module DEBUGGER__
116
120
 
117
121
  self.extend(UI_CDP)
118
122
  @repl = false
119
- @web_sock = UI_CDP::WebSocket.new(@sock)
120
- @web_sock.handshake
123
+ CONFIG.set_config no_color: true
124
+
125
+ @ws_server = UI_CDP::WebSocketServer.new(@sock)
126
+ @ws_server.handshake
121
127
  else
122
128
  raise "Greeting message error: #{g}"
123
129
  end
@@ -178,7 +184,7 @@ module DEBUGGER__
178
184
 
179
185
  def sigurg_overridden? prev_handler
180
186
  case prev_handler
181
- when "SYSTEM_DEFAULT"
187
+ when "SYSTEM_DEFAULT", "DEFAULT"
182
188
  false
183
189
  when Proc
184
190
  if prev_handler.source_location[0] == __FILE__
@@ -191,10 +197,19 @@ module DEBUGGER__
191
197
  end
192
198
  end
193
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
+
194
209
  def setup_interrupt
195
- prev_handler = trap(:SIGURG) do
210
+ prev_handler = trap(TRAP_SIGNAL) do
196
211
  # $stderr.puts "trapped SIGINT"
197
- ThreadClient.current.on_trap :SIGURG
212
+ ThreadClient.current.on_trap TRAP_SIGNAL
198
213
 
199
214
  case prev_handler
200
215
  when Proc
@@ -209,7 +224,7 @@ module DEBUGGER__
209
224
  end
210
225
  yield
211
226
  ensure
212
- trap(:SIGURG, prev_handler)
227
+ trap(TRAP_SIGNAL, prev_handler)
213
228
  end
214
229
 
215
230
  attr_reader :reader_thread
@@ -297,7 +312,7 @@ module DEBUGGER__
297
312
 
298
313
  def pause
299
314
  # $stderr.puts "DEBUG: pause request"
300
- Process.kill(:SIGURG, Process.pid)
315
+ Process.kill(TRAP_SIGNAL, Process.pid)
301
316
  end
302
317
 
303
318
  def quit n
@@ -328,29 +343,37 @@ module DEBUGGER__
328
343
  super()
329
344
  end
330
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
+
331
359
  def accept
332
360
  retry_cnt = 0
333
361
  super # for fork
334
362
 
335
363
  begin
336
364
  Socket.tcp_server_sockets @host, @port do |socks|
337
- 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.
338
366
  rdbg = File.expand_path('../../exe/rdbg', __dir__)
339
367
 
340
- DEBUGGER__.warn "Debugger can attach via TCP/IP (#{addr})"
368
+ DEBUGGER__.warn "Debugger can attach via TCP/IP (#{@addr})"
341
369
  DEBUGGER__.info <<~EOS
342
370
  With rdbg, use the following command line:
343
371
  #
344
- # #{rdbg} --attach #{addr.split(':').join(' ')}
372
+ # #{rdbg} --attach #{@addr.split(':').join(' ')}
345
373
  #
346
374
  EOS
347
375
 
348
- DEBUGGER__.warn <<~EOS if CONFIG[:open_frontend] == 'chrome'
349
- With Chrome browser, type the following URL in the address-bar:
350
-
351
- devtools://devtools/bundled/inspector.html?ws=#{addr}
352
-
353
- EOS
376
+ chrome_setup if CONFIG[:open_frontend] == 'chrome'
354
377
 
355
378
  Socket.accept_loop(socks) do |sock, client|
356
379
  @client_addr = client
@@ -387,61 +410,8 @@ module DEBUGGER__
387
410
  end
388
411
 
389
412
  def vscode_setup
390
- require 'tmpdir'
391
- require 'json'
392
- require 'fileutils'
393
-
394
- dir = Dir.mktmpdir("ruby-debug-vscode-")
395
- at_exit{
396
- FileUtils.rm_rf dir
397
- }
398
- Dir.chdir(dir) do
399
- Dir.mkdir('.vscode')
400
- open('README.rb', 'w'){|f|
401
- f.puts <<~MSG
402
- # Wait for starting the attaching to the Ruby process
403
- # This file will be removed at the end of the debuggee process.
404
- #
405
- # Note that vscode-rdbg extension is needed. Please install if you don't have.
406
- MSG
407
- }
408
- open('.vscode/launch.json', 'w'){|f|
409
- f.puts JSON.pretty_generate({
410
- version: '0.2.0',
411
- configurations: [
412
- {
413
- type: "rdbg",
414
- name: "Attach with rdbg",
415
- request: "attach",
416
- rdbgPath: File.expand_path('../../exe/rdbg', __dir__),
417
- debugPort: @sock_path,
418
- autoAttach: true,
419
- }
420
- ]
421
- })
422
- }
423
- end
424
-
425
- cmds = ['code', "#{dir}/", "#{dir}/README.rb"]
426
- cmdline = cmds.join(' ')
427
- ssh_cmdline = "code --remote ssh-remote+[SSH hostname] #{dir}/ #{dir}/README.rb"
428
-
429
- STDERR.puts "Launching: #{cmdline}"
430
- env = ENV.delete_if{|k, h| /RUBY/ =~ k}.to_h
431
-
432
- unless system(env, *cmds)
433
- DEBUGGER__.warn <<~MESSAGE
434
- Can not invoke the command.
435
- Use the command-line on your terminal (with modification if you need).
436
-
437
- #{cmdline}
438
-
439
- If your application is running on a SSH remote host, please try:
440
-
441
- #{ssh_cmdline}
442
-
443
- MESSAGE
444
- end
413
+ require_relative 'server_dap'
414
+ UI_DAP.setup @sock_path
445
415
  end
446
416
 
447
417
  def accept