debug 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +116 -5
- data/Rakefile +9 -6
- data/ext/debug/debug.c +2 -1
- data/ext/debug/extconf.rb +2 -0
- data/lib/debug/breakpoint.rb +2 -2
- data/lib/debug/client.rb +72 -47
- data/lib/debug/config.rb +48 -11
- data/lib/debug/console.rb +92 -25
- data/lib/debug/frame_info.rb +3 -3
- data/lib/debug/local.rb +4 -1
- data/lib/debug/prelude.rb +49 -0
- data/lib/debug/server.rb +161 -17
- data/lib/debug/server_cdp.rb +412 -0
- data/lib/debug/server_dap.rb +53 -23
- data/lib/debug/session.rb +398 -120
- data/lib/debug/thread_client.rb +4 -2
- data/lib/debug/version.rb +1 -1
- data/misc/README.md.erb +95 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: adddd814397fedb45de84db6ccb2dc49c3aefae141e73b156e3b87c29a3edf60
|
4
|
+
data.tar.gz: 0b0cb92d077f04ed9f7bfa1f79f56f35dc4dc9054f27ea3608d23c5f0d462274
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e60eb57c1ec6c164d6956e777f8ac52e15ba84c13b97443650ac67f2b503397cfc57d9f0b897f331946e7200067227d61e7b81f459c5b42e44098dbbe9161ef
|
7
|
+
data.tar.gz: 3a377c3da4482103142fbece04cb896522f952aa3d43f316f50dd699f35f0c24db100df3e706e6d86cbc752021800bbfdff6131a95023d497741d68c396e5ed7
|
data/README.md
CHANGED
@@ -11,7 +11,9 @@ New debug.rb has several advantages:
|
|
11
11
|
* [Remote debugging](#remote-debugging): Support remote debugging natively.
|
12
12
|
* UNIX domain socket
|
13
13
|
* TCP/IP
|
14
|
-
*
|
14
|
+
* Integeration with rich debugger frontend
|
15
|
+
* VSCode/DAP ([VSCode rdbg Ruby Debugger - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=KoichiSasada.vscode-rdbg))
|
16
|
+
* Chrome DevTools
|
15
17
|
* Extensible: application can introduce debugging support with several ways:
|
16
18
|
* By `rdbg` command
|
17
19
|
* By loading libraries with `-r` command line option
|
@@ -336,6 +338,97 @@ By default, UNIX domain socket is used for the debugging port. To use TCP/IP, yo
|
|
336
338
|
$ RUBY_DEBUG_PORT=12345 ruby target.rb
|
337
339
|
```
|
338
340
|
|
341
|
+
### Integration with external debugger frontend
|
342
|
+
|
343
|
+
You can attach with external debuger frontend with VSCode and Chrome.
|
344
|
+
|
345
|
+
```
|
346
|
+
$ rdbg --open=[frontend] target.rb
|
347
|
+
```
|
348
|
+
|
349
|
+
will open a debug port and `[frontned]` can attache to the port.
|
350
|
+
|
351
|
+
Also `open` command allows opening the debug port.
|
352
|
+
|
353
|
+
#### VSCode integration
|
354
|
+
|
355
|
+
If you don't run a debuggee Ruby process on VSCode, you can attach with VSCode later with the fowllowing steps.
|
356
|
+
|
357
|
+
`rdbg --open=vscode` opens the debug port and tries to invoke the VSCode (`code` command).
|
358
|
+
|
359
|
+
```
|
360
|
+
$ rdbg --open=vscode target.rb
|
361
|
+
DEBUGGER: Debugger can attach via UNIX domain socket (/tmp/ruby-debug-sock-1000/ruby-debug-ko1-27706)
|
362
|
+
DEBUGGER: wait for debugger connection...
|
363
|
+
Launching: code /tmp/ruby-debug-vscode-20211014-27706-gd7e85/ /tmp/ruby-debug-vscode-20211014-27706-gd7e85/README.rb
|
364
|
+
DEBUGGER: Connected.
|
365
|
+
```
|
366
|
+
|
367
|
+
And it tris to invoke the new VSCode window and VSCode starts attaching to the debuggee Ruby program automatically.
|
368
|
+
|
369
|
+
You can also use `open vscode` command in REPL.
|
370
|
+
|
371
|
+
```
|
372
|
+
$ rdbg target.rb
|
373
|
+
[1, 8] in target.rb
|
374
|
+
1|
|
375
|
+
=> 2| p a = 1
|
376
|
+
3| p b = 2
|
377
|
+
4| p c = 3
|
378
|
+
5| p d = 4
|
379
|
+
6| p e = 5
|
380
|
+
7|
|
381
|
+
8| __END__
|
382
|
+
=>#0 <main> at target.rb:2
|
383
|
+
(rdbg) open vscode # command
|
384
|
+
DEBUGGER: wait for debugger connection...
|
385
|
+
DEBUGGER: Debugger can attach via UNIX domain socket (/tmp/ruby-debug-sock-1000/ruby-debug-ko1-28337)
|
386
|
+
Launching: code /tmp/ruby-debug-vscode-20211014-28337-kg9dm/ /tmp/ruby-debug-vscode-20211014-28337-kg9dm/README.rb
|
387
|
+
DEBUGGER: Connected.
|
388
|
+
```
|
389
|
+
|
390
|
+
If the machine which runs the Ruby process doesn't have a `code` command, the following message will be shown:
|
391
|
+
|
392
|
+
```
|
393
|
+
(rdbg) open vscode
|
394
|
+
DEBUGGER: wait for debugger connection...
|
395
|
+
DEBUGGER: Debugger can attach via UNIX domain socket (/tmp/ruby-debug-sock-1000/ruby-debug-ko1-455)
|
396
|
+
Launching: code /tmp/ruby-debug-vscode-20211014-455-gtjpwi/ /tmp/ruby-debug-vscode-20211014-455-gtjpwi/README.rb
|
397
|
+
DEBUGGER: Can not invoke the command.
|
398
|
+
Use the command-line on your terminal (with modification if you need).
|
399
|
+
|
400
|
+
code /tmp/ruby-debug-vscode-20211014-455-gtjpwi/ /tmp/ruby-debug-vscode-20211014-455-gtjpwi/README.rb
|
401
|
+
|
402
|
+
If your application is running on a SSH remote host, please try:
|
403
|
+
|
404
|
+
code --remote ssh-remote+[SSH hostname] /tmp/ruby-debug-vscode-20211014-455-gtjpwi/ /tmp/ruby-debug-vscode-20211014-455-gtjpwi/README.rb
|
405
|
+
|
406
|
+
```
|
407
|
+
|
408
|
+
and try to use proposed commands.
|
409
|
+
|
410
|
+
Note that you can attach with `rdbg --attach` and continue REPL debugging.
|
411
|
+
|
412
|
+
#### Chrome DevTool integration
|
413
|
+
|
414
|
+
With `rdbg --open=chrome` command will shows the following message.
|
415
|
+
|
416
|
+
```
|
417
|
+
$ rdbg target.rb --open=chrome
|
418
|
+
DEBUGGER: Debugger can attach via TCP/IP (127.0.0.1:43633)
|
419
|
+
DEBUGGER: With Chrome browser, type the following URL in the address-bar:
|
420
|
+
|
421
|
+
devtools://devtools/bundled/inspector.html?ws=127.0.0.1:43633
|
422
|
+
|
423
|
+
DEBUGGER: wait for debugger connection...
|
424
|
+
```
|
425
|
+
|
426
|
+
Type `devtools://devtools/bundled/inspector.html?ws=127.0.0.1:43633` in the address-bar on Chrome browser, and you can continue the debugging with chrome browser.
|
427
|
+
|
428
|
+
Also `open chrome` command works like `open vscode`.
|
429
|
+
|
430
|
+
For more information about how to use Chrome debugging, you might want to read [here](https://developer.chrome.com/docs/devtools/)
|
431
|
+
|
339
432
|
## Configuration
|
340
433
|
|
341
434
|
You can configure the debugger's behavior with debug commands and environment variables.
|
@@ -367,7 +460,7 @@ config set no_color true
|
|
367
460
|
* `RUBY_DEBUG_SKIP_NOSRC` (`skip_nosrc`): Skip on no source code lines (default: false)
|
368
461
|
* `RUBY_DEBUG_KEEP_ALLOC_SITE` (`keep_alloc_site`): Keep allocation site and p, pp shows it (default: false)
|
369
462
|
* `RUBY_DEBUG_POSTMORTEM` (`postmortem`): Enable postmortem debug (default: false)
|
370
|
-
* `
|
463
|
+
* `RUBY_DEBUG_FORK_MODE` (`fork_mode`): Control which process activates a debugger after fork (both/parent/child) (default: both)
|
371
464
|
* `RUBY_DEBUG_SIGDUMP_SIG` (`sigdump_sig`): Sigdump signal (default: disabled)
|
372
465
|
|
373
466
|
* BOOT
|
@@ -376,6 +469,8 @@ config set no_color true
|
|
376
469
|
* `RUBY_DEBUG_INIT_SCRIPT` (`init_script`): debug command script path loaded at first stop
|
377
470
|
* `RUBY_DEBUG_COMMANDS` (`commands`): debug commands invoked at first stop. commands should be separated by ';;'
|
378
471
|
* `RUBY_DEBUG_NO_RC` (`no_rc`): ignore loading ~/.rdbgrc(.rb)
|
472
|
+
* `RUBY_DEBUG_HISTORY_FILE` (`history_file`): history file (default: ~/.rdbg_history)
|
473
|
+
* `RUBY_DEBUG_SAVE_HISTORY` (`save_history`): maximum save history lines (default: 10,000)
|
379
474
|
|
380
475
|
* REMOTE
|
381
476
|
* `RUBY_DEBUG_PORT` (`port`): TCP/IP remote debugging: port
|
@@ -383,6 +478,10 @@ config set no_color true
|
|
383
478
|
* `RUBY_DEBUG_SOCK_PATH` (`sock_path`): UNIX Domain Socket remote debugging: socket path
|
384
479
|
* `RUBY_DEBUG_SOCK_DIR` (`sock_dir`): UNIX Domain Socket remote debugging: socket directory
|
385
480
|
* `RUBY_DEBUG_COOKIE` (`cookie`): Cookie for negotiation
|
481
|
+
* `RUBY_DEBUG_OPEN_FRONTEND` (`open_frontend`): frontend used by open command (vscode, chrome, default: rdbg).
|
482
|
+
|
483
|
+
* OBSOLETE
|
484
|
+
* `RUBY_DEBUG_PARENT_ON_FORK` (`parent_on_fork`): Keep debugging parent process on fork (default: false)
|
386
485
|
|
387
486
|
### Initial scripts
|
388
487
|
|
@@ -596,6 +695,15 @@ The `<...>` notation means the argument.
|
|
596
695
|
* Set <name> to default.
|
597
696
|
* `source <file>`
|
598
697
|
* Evaluate lines in `<file>` as debug commands.
|
698
|
+
* `open`
|
699
|
+
* open debuggee port on UNIX domain socket and wait for attaching.
|
700
|
+
* Note that `open` command is EXPERIMENTAL.
|
701
|
+
* `open [<host>:]<port>`
|
702
|
+
* open debuggee port on TCP/IP with given `[<host>:]<port>` and wait for attaching.
|
703
|
+
* `open vscode`
|
704
|
+
* open debuggee port for VSCode and launch VSCode if available.
|
705
|
+
* `open chrome`
|
706
|
+
* open debuggee port for Chrome and wait for attaching.
|
599
707
|
|
600
708
|
### Help
|
601
709
|
|
@@ -698,9 +806,10 @@ Debug console mode:
|
|
698
806
|
The first argument should be a command name in $PATH.
|
699
807
|
Example: 'rdbg -c bundle exec rake test'
|
700
808
|
|
701
|
-
-O, --open
|
702
|
-
If TCP/IP options are not given,
|
703
|
-
|
809
|
+
-O, --open=[FRONTEND] Start remote debugging with opening the network port.
|
810
|
+
If TCP/IP options are not given, a UNIX domain socket will be used.
|
811
|
+
If FRONTEND is given, prepare for the FRONTEND.
|
812
|
+
Now rdbg, vscode and chrome is supported.
|
704
813
|
--sock-path=SOCK_PATH UNIX Domain socket path
|
705
814
|
--port=PORT Listening TCP/IP port
|
706
815
|
--host=HOST Listening TCP/IP host
|
@@ -716,6 +825,7 @@ Debug console mode:
|
|
716
825
|
'rdbg -O target.rb foo bar' starts and accepts attaching with UNIX domain socket.
|
717
826
|
'rdbg -O --port 1234 target.rb foo bar' starts accepts attaching with TCP/IP localhost:1234.
|
718
827
|
'rdbg -O --port 1234 -- -r foo -e bar' starts accepts attaching with TCP/IP localhost:1234.
|
828
|
+
'rdbg target.rb -O chrome --port 1234' starts and accepts connecting from Chrome Devtools with localhost:1234.
|
719
829
|
|
720
830
|
Attach mode:
|
721
831
|
-A, --attach Attach to debuggee process.
|
@@ -750,3 +860,4 @@ Please also check the [contributing guideline](/CONTRIBUTING.md).
|
|
750
860
|
# Acknowledgement
|
751
861
|
|
752
862
|
* Some tests are based on [deivid-rodriguez/byebug: Debugging in Ruby 2](https://github.com/deivid-rodriguez/byebug)
|
863
|
+
* Several codes in `server_cdp.rb` are based on [geoffreylitt/ladybug: Visual Debugger](https://github.com/geoffreylitt/ladybug)
|
data/Rakefile
CHANGED
@@ -7,14 +7,17 @@ Rake::TestTask.new(:test) do |t|
|
|
7
7
|
t.test_files = FileList["test/**/*_test.rb"]
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
task :build => :compile
|
13
|
-
|
14
|
-
Rake::ExtensionTask.new("debug") do |ext|
|
15
|
-
|
10
|
+
begin
|
11
|
+
require "rake/extensiontask"
|
12
|
+
task :build => :compile
|
13
|
+
|
14
|
+
Rake::ExtensionTask.new("debug") do |ext|
|
15
|
+
ext.lib_dir = "lib/debug"
|
16
|
+
end
|
17
|
+
rescue LoadError
|
16
18
|
end
|
17
19
|
|
20
|
+
|
18
21
|
task :default => [:clobber, :compile, 'README.md', :test]
|
19
22
|
|
20
23
|
file 'README.md' => ['lib/debug/session.rb', 'lib/debug/config.rb',
|
data/ext/debug/debug.c
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
#include "ruby/ruby.h"
|
3
3
|
#include "ruby/debug.h"
|
4
4
|
#include "ruby/encoding.h"
|
5
|
-
|
5
|
+
#include "debug_version.h"
|
6
6
|
//
|
7
7
|
static VALUE rb_mDebugger;
|
8
8
|
|
@@ -130,5 +130,6 @@ Init_debug(void)
|
|
130
130
|
rb_define_singleton_method(rb_mDebugger, "capture_frames", capture_frames, 1);
|
131
131
|
rb_define_singleton_method(rb_mDebugger, "frame_depth", frame_depth, 0);
|
132
132
|
rb_define_singleton_method(rb_mDebugger, "create_method_added_tracker", create_method_added_tracker, 0);
|
133
|
+
rb_define_const(rb_mDebugger, "SO_VERSION", rb_str_new2(RUBY_DEBUG_VERSION));
|
133
134
|
Init_iseq_collector();
|
134
135
|
}
|
data/ext/debug/extconf.rb
CHANGED
data/lib/debug/breakpoint.rb
CHANGED
@@ -437,7 +437,7 @@ module DEBUGGER__
|
|
437
437
|
end
|
438
438
|
end
|
439
439
|
|
440
|
-
rescue ArgumentError
|
440
|
+
rescue ArgumentError
|
441
441
|
raise if retried
|
442
442
|
retried = true
|
443
443
|
|
@@ -458,7 +458,7 @@ module DEBUGGER__
|
|
458
458
|
@override_method = true if @method
|
459
459
|
retry
|
460
460
|
end
|
461
|
-
rescue Exception
|
461
|
+
rescue Exception
|
462
462
|
raise unless added
|
463
463
|
end
|
464
464
|
|
data/lib/debug/client.rb
CHANGED
@@ -13,20 +13,59 @@ module DEBUGGER__
|
|
13
13
|
class CommandLineOptionError < Exception; end
|
14
14
|
|
15
15
|
class Client
|
16
|
-
|
17
|
-
|
16
|
+
class << self
|
17
|
+
def util name
|
18
|
+
case name
|
19
|
+
when 'gen-sockpath'
|
20
|
+
puts DEBUGGER__.create_unix_domain_socket_name
|
21
|
+
when 'list-socks'
|
22
|
+
cleanup_unix_domain_sockets
|
23
|
+
puts list_connections
|
24
|
+
when 'init'
|
25
|
+
if ARGV.shift == '-'
|
26
|
+
puts <<~EOS
|
27
|
+
export RUBYOPT="-r #{__dir__}/prelude $(RUBYOPT)"
|
28
|
+
EOS
|
29
|
+
else
|
30
|
+
puts <<~EOS
|
31
|
+
# add the following lines in your .bash_profile
|
32
|
+
|
33
|
+
eval "$(rdbg init -)"
|
34
|
+
EOS
|
35
|
+
end
|
36
|
+
else
|
37
|
+
raise "Unknown utility: #{name}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def cleanup_unix_domain_sockets
|
42
|
+
Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*') do |file|
|
43
|
+
if /(\d+)$/ =~ file
|
44
|
+
begin
|
45
|
+
Process.kill(0, $1.to_i)
|
46
|
+
rescue Errno::EPERM
|
47
|
+
rescue Errno::ESRCH
|
48
|
+
File.unlink(file)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def list_connections
|
55
|
+
Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*')
|
56
|
+
end
|
57
|
+
end
|
18
58
|
|
59
|
+
def initialize argv
|
60
|
+
@multi_process = false
|
61
|
+
@pid = nil
|
19
62
|
@console = Console.new
|
20
63
|
|
21
64
|
case argv.size
|
22
65
|
when 0
|
23
66
|
connect_unix
|
24
67
|
when 1
|
25
|
-
|
26
|
-
when /-h/, /--help/
|
27
|
-
help
|
28
|
-
exit
|
29
|
-
when /\A\d+\z/
|
68
|
+
if /\A\d+\z/ =~ (arg = argv.shift.strip)
|
30
69
|
connect_tcp nil, arg.to_i
|
31
70
|
else
|
32
71
|
connect_unix arg
|
@@ -39,41 +78,22 @@ module DEBUGGER__
|
|
39
78
|
|
40
79
|
@width = IO.console_size[1]
|
41
80
|
@width = 80 if @width == 0
|
42
|
-
@width_changed = false
|
43
81
|
|
44
82
|
send "version: #{VERSION} width: #{@width} cookie: #{CONFIG[:cookie]}"
|
45
83
|
end
|
46
84
|
|
47
|
-
def
|
48
|
-
@console.
|
85
|
+
def deactivate
|
86
|
+
@console.deactivate if @console
|
49
87
|
end
|
50
88
|
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
puts DEBUGGER__.create_unix_domain_socket_name
|
55
|
-
when 'list-socks'
|
56
|
-
cleanup_unix_domain_sockets
|
57
|
-
puts list_connections
|
89
|
+
def readline
|
90
|
+
if @multi_process
|
91
|
+
@console.readline "(rdbg:remote\##{@pid}) "
|
58
92
|
else
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
|
63
|
-
def cleanup_unix_domain_sockets
|
64
|
-
Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*') do |file|
|
65
|
-
if /(\d+)$/ =~ file
|
66
|
-
begin
|
67
|
-
Process.kill(0, $1.to_i)
|
68
|
-
rescue Errno::ESRCH
|
69
|
-
File.unlink(file)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def list_connections
|
76
|
-
Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*')
|
93
|
+
@console.readline "(rdbg:remote) "
|
94
|
+
end.tap{|line|
|
95
|
+
p readline: line
|
96
|
+
}
|
77
97
|
end
|
78
98
|
|
79
99
|
def connect_unix name = nil
|
@@ -84,8 +104,9 @@ module DEBUGGER__
|
|
84
104
|
@s = Socket.unix(File.join(DEBUGGER__.unix_domain_socket_dir, name))
|
85
105
|
end
|
86
106
|
else
|
87
|
-
cleanup_unix_domain_sockets
|
88
|
-
files = list_connections
|
107
|
+
Client.cleanup_unix_domain_sockets
|
108
|
+
files = Client.list_connections
|
109
|
+
|
89
110
|
case files.size
|
90
111
|
when 0
|
91
112
|
$stderr.puts "No debug session is available."
|
@@ -117,15 +138,19 @@ module DEBUGGER__
|
|
117
138
|
}
|
118
139
|
trap(:SIGWINCH){
|
119
140
|
@width = IO.console_size[1]
|
120
|
-
@width_changed = true
|
121
141
|
}
|
122
142
|
|
123
143
|
while line = @s.gets
|
124
144
|
p recv: line if $VERBOSE
|
125
145
|
case line
|
146
|
+
|
126
147
|
when /^out (.*)/
|
127
148
|
puts "#{$1}"
|
128
|
-
|
149
|
+
|
150
|
+
when /^input (.+)/
|
151
|
+
pid = $1
|
152
|
+
@multi_process = true if @pid && @pid != pid
|
153
|
+
@pid = pid
|
129
154
|
prev_trap = trap(:SIGINT, 'DEFAULT')
|
130
155
|
|
131
156
|
begin
|
@@ -137,18 +162,16 @@ module DEBUGGER__
|
|
137
162
|
end
|
138
163
|
|
139
164
|
line = (line || 'quit').strip
|
165
|
+
send "command #{pid} #{@width} #{line}"
|
140
166
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
167
|
+
when /^ask (\d+) (.*)/
|
168
|
+
pid = $1
|
169
|
+
print $2
|
170
|
+
send "answer #{pid} #{gets || ''}"
|
145
171
|
|
146
|
-
send "command #{line}"
|
147
|
-
when /^ask (.*)/
|
148
|
-
print $1
|
149
|
-
send "answer #{gets || ''}"
|
150
172
|
when /^quit/
|
151
173
|
raise 'quit'
|
174
|
+
|
152
175
|
else
|
153
176
|
puts "(unknown) #{line.inspect}"
|
154
177
|
end
|
@@ -156,6 +179,8 @@ module DEBUGGER__
|
|
156
179
|
rescue
|
157
180
|
STDERR.puts "disconnected (#{$!})"
|
158
181
|
exit
|
182
|
+
ensure
|
183
|
+
deactivate
|
159
184
|
end
|
160
185
|
end
|
161
186
|
end
|
data/lib/debug/config.rb
CHANGED
@@ -24,7 +24,7 @@ module DEBUGGER__
|
|
24
24
|
skip_nosrc: ['RUBY_DEBUG_SKIP_NOSRC', "CONTROL: Skip on no source code lines (default: false)", :bool],
|
25
25
|
keep_alloc_site:['RUBY_DEBUG_KEEP_ALLOC_SITE',"CONTROL: Keep allocation site and p, pp shows it (default: false)", :bool],
|
26
26
|
postmortem: ['RUBY_DEBUG_POSTMORTEM', "CONTROL: Enable postmortem debug (default: false)", :bool],
|
27
|
-
|
27
|
+
fork_mode: ['RUBY_DEBUG_FORK_MODE', "CONTROL: Control which process activates a debugger after fork (both/parent/child) (default: both)", :forkmode],
|
28
28
|
sigdump_sig: ['RUBY_DEBUG_SIGDUMP_SIG', "CONTROL: Sigdump signal (default: disabled)"],
|
29
29
|
|
30
30
|
# boot setting
|
@@ -33,13 +33,19 @@ module DEBUGGER__
|
|
33
33
|
init_script: ['RUBY_DEBUG_INIT_SCRIPT', "BOOT: debug command script path loaded at first stop"],
|
34
34
|
commands: ['RUBY_DEBUG_COMMANDS', "BOOT: debug commands invoked at first stop. commands should be separated by ';;'"],
|
35
35
|
no_rc: ['RUBY_DEBUG_NO_RC', "BOOT: ignore loading ~/.rdbgrc(.rb)", :bool],
|
36
|
+
history_file: ['RUBY_DEBUG_HISTORY_FILE',"BOOT: history file (default: ~/.rdbg_history)"],
|
37
|
+
save_history: ['RUBY_DEBUG_SAVE_HISTORY',"BOOT: maximum save history lines (default: 10,000)"],
|
36
38
|
|
37
39
|
# remote setting
|
38
|
-
port: ['RUBY_DEBUG_PORT',
|
39
|
-
host: ['RUBY_DEBUG_HOST',
|
40
|
-
sock_path: ['RUBY_DEBUG_SOCK_PATH',
|
41
|
-
sock_dir: ['RUBY_DEBUG_SOCK_DIR',
|
42
|
-
cookie: ['RUBY_DEBUG_COOKIE',
|
40
|
+
port: ['RUBY_DEBUG_PORT', "REMOTE: TCP/IP remote debugging: port"],
|
41
|
+
host: ['RUBY_DEBUG_HOST', "REMOTE: TCP/IP remote debugging: host (localhost if not given)"],
|
42
|
+
sock_path: ['RUBY_DEBUG_SOCK_PATH', "REMOTE: UNIX Domain Socket remote debugging: socket path"],
|
43
|
+
sock_dir: ['RUBY_DEBUG_SOCK_DIR', "REMOTE: UNIX Domain Socket remote debugging: socket directory"],
|
44
|
+
cookie: ['RUBY_DEBUG_COOKIE', "REMOTE: Cookie for negotiation"],
|
45
|
+
open_frontend: ['RUBY_DEBUG_OPEN_FRONTEND',"REMOTE: frontend used by open command (vscode, chrome, default: rdbg)."],
|
46
|
+
|
47
|
+
# obsolete
|
48
|
+
parent_on_fork: ['RUBY_DEBUG_PARENT_ON_FORK', "OBSOLETE: Keep debugging parent process on fork (default: false)", :bool],
|
43
49
|
}.freeze
|
44
50
|
|
45
51
|
CONFIG_MAP = CONFIG_SET.map{|k, (ev, desc)| [k, ev]}.to_h.freeze
|
@@ -57,6 +63,10 @@ module DEBUGGER__
|
|
57
63
|
update self.class.parse_argv(argv)
|
58
64
|
end
|
59
65
|
|
66
|
+
def inspect
|
67
|
+
config.inspect
|
68
|
+
end
|
69
|
+
|
60
70
|
def [](key)
|
61
71
|
config[key]
|
62
72
|
end
|
@@ -79,7 +89,7 @@ module DEBUGGER__
|
|
79
89
|
end
|
80
90
|
|
81
91
|
def append_config key, val
|
82
|
-
conf =
|
92
|
+
conf = config.dup
|
83
93
|
|
84
94
|
if CONFIG_SET[key]
|
85
95
|
if CONFIG_SET[key][2] == :path
|
@@ -187,6 +197,13 @@ module DEBUGGER__
|
|
187
197
|
else
|
188
198
|
raise "Unknown loglevel: #{valstr}"
|
189
199
|
end
|
200
|
+
when :forkmode
|
201
|
+
case sym = valstr.to_sym
|
202
|
+
when :parent, :child, :both, nil
|
203
|
+
sym
|
204
|
+
else
|
205
|
+
raise "unknown fork mode: #{sym}"
|
206
|
+
end
|
190
207
|
when :path # array of String
|
191
208
|
valstr.split(/:/).map{|e|
|
192
209
|
if /\A\/(.+)\/\z/ =~ e
|
@@ -255,10 +272,12 @@ module DEBUGGER__
|
|
255
272
|
|
256
273
|
o.separator ''
|
257
274
|
|
258
|
-
o.on('-O', '--open', 'Start remote debugging with opening the network port.',
|
259
|
-
|
260
|
-
|
275
|
+
o.on('-O', '--open=[FRONTEND]', 'Start remote debugging with opening the network port.',
|
276
|
+
'If TCP/IP options are not given, a UNIX domain socket will be used.',
|
277
|
+
'If FRONTEND is given, prepare for the FRONTEND.',
|
278
|
+
'Now rdbg, vscode and chrome is supported.') do |f|
|
261
279
|
config[:remote] = true
|
280
|
+
config[:open_frontend] = f.downcase if f
|
262
281
|
end
|
263
282
|
o.on('--sock-path=SOCK_PATH', 'UNIX Domain socket path') do |path|
|
264
283
|
config[:sock_path] = path
|
@@ -286,6 +305,7 @@ module DEBUGGER__
|
|
286
305
|
o.separator " '#{rdbg} -O target.rb foo bar' starts and accepts attaching with UNIX domain socket."
|
287
306
|
o.separator " '#{rdbg} -O --port 1234 target.rb foo bar' starts accepts attaching with TCP/IP localhost:1234."
|
288
307
|
o.separator " '#{rdbg} -O --port 1234 -- -r foo -e bar' starts accepts attaching with TCP/IP localhost:1234."
|
308
|
+
o.separator " '#{rdbg} target.rb -O chrome --port 1234' starts and accepts connecting from Chrome Devtools with localhost:1234."
|
289
309
|
|
290
310
|
o.separator ''
|
291
311
|
o.separator 'Attach mode:'
|
@@ -313,7 +333,7 @@ module DEBUGGER__
|
|
313
333
|
|
314
334
|
o.on('--util=NAME', 'Utility mode (used by tools)') do |name|
|
315
335
|
require_relative 'client'
|
316
|
-
Client.
|
336
|
+
Client.util(name)
|
317
337
|
exit
|
318
338
|
end
|
319
339
|
|
@@ -352,9 +372,26 @@ module DEBUGGER__
|
|
352
372
|
## Unix domain socket configuration
|
353
373
|
|
354
374
|
def self.unix_domain_socket_dir
|
375
|
+
require 'tmpdir'
|
376
|
+
|
355
377
|
case
|
356
378
|
when path = CONFIG[:sock_dir]
|
357
379
|
when path = ENV['XDG_RUNTIME_DIR']
|
380
|
+
when tmpdir = Dir.tmpdir
|
381
|
+
path = File.join(tmpdir, "ruby-debug-sock-#{Process.uid}")
|
382
|
+
|
383
|
+
if File.exist?(path)
|
384
|
+
fs = File.stat(path)
|
385
|
+
unless (dir_uid = fs.uid) == (uid = Process.uid)
|
386
|
+
raise "#{path} uid is #{dir_uid}, but Process.uid is #{uid}"
|
387
|
+
end
|
388
|
+
unless (dir_mode = fs.mode) == 040700 # 4: dir, 7:rwx
|
389
|
+
raise "#{path}'s mode is #{dir_mode.to_s(8)} (should be 040700)"
|
390
|
+
end
|
391
|
+
else
|
392
|
+
d = Dir.mktmpdir
|
393
|
+
File.rename(d, path)
|
394
|
+
end
|
358
395
|
when home = ENV['HOME']
|
359
396
|
path = File.join(home, '.ruby-debug-sock')
|
360
397
|
|