debug 1.2.2 → 1.3.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.
- checksums.yaml +4 -4
- data/README.md +116 -5
- 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 +69 -46
- data/lib/debug/config.rb +74 -21
- data/lib/debug/console.rb +92 -25
- data/lib/debug/local.rb +22 -1
- data/lib/debug/prelude.rb +49 -0
- data/lib/debug/server.rb +186 -25
- data/lib/debug/server_cdp.rb +412 -0
- data/lib/debug/server_dap.rb +53 -23
- data/lib/debug/session.rb +387 -120
- data/lib/debug/thread_client.rb +4 -2
- data/lib/debug/version.rb +1 -1
- data/misc/README.md.erb +95 -1
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 948301b2d85d9acb8758ae20e63a60d0253dc1d1e1bf5c2ddc276abb39d12993
|
4
|
+
data.tar.gz: 2e6b7c89ee568710d52d3fcaff1ff5eb44db71c4e296e039a6f21f4e5de9b9ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd5237c7fc194760f33cdd97c007fe1c879ed4140342821972d2385a612bd5fd4c8faffd2a3763adea1378931be13e65d46e2a23f5997412ac96c6e7c802e0d2
|
7
|
+
data.tar.gz: 396eab432e765065288f49cda52ce8a4449ee6c97465bde2ef70ec8ca39678b80831748b551d6aa6e4417c1c6512b8b0f8caf4371516a9178181582b9bf9542c
|
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/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
|
18
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
|
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,43 +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
|
-
end
|
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
|
93
|
+
@console.readline "(rdbg:remote) "
|
72
94
|
end
|
73
95
|
end
|
74
96
|
|
75
|
-
def list_connections
|
76
|
-
Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*')
|
77
|
-
end
|
78
|
-
|
79
97
|
def connect_unix name = nil
|
80
98
|
if name
|
81
99
|
if File.exist? name
|
@@ -84,8 +102,9 @@ module DEBUGGER__
|
|
84
102
|
@s = Socket.unix(File.join(DEBUGGER__.unix_domain_socket_dir, name))
|
85
103
|
end
|
86
104
|
else
|
87
|
-
cleanup_unix_domain_sockets
|
88
|
-
files = list_connections
|
105
|
+
Client.cleanup_unix_domain_sockets
|
106
|
+
files = Client.list_connections
|
107
|
+
|
89
108
|
case files.size
|
90
109
|
when 0
|
91
110
|
$stderr.puts "No debug session is available."
|
@@ -117,15 +136,19 @@ module DEBUGGER__
|
|
117
136
|
}
|
118
137
|
trap(:SIGWINCH){
|
119
138
|
@width = IO.console_size[1]
|
120
|
-
@width_changed = true
|
121
139
|
}
|
122
140
|
|
123
141
|
while line = @s.gets
|
124
142
|
p recv: line if $VERBOSE
|
125
143
|
case line
|
144
|
+
|
126
145
|
when /^out (.*)/
|
127
146
|
puts "#{$1}"
|
128
|
-
|
147
|
+
|
148
|
+
when /^input (.+)/
|
149
|
+
pid = $1
|
150
|
+
@multi_process = true if @pid && @pid != pid
|
151
|
+
@pid = pid
|
129
152
|
prev_trap = trap(:SIGINT, 'DEFAULT')
|
130
153
|
|
131
154
|
begin
|
@@ -137,18 +160,16 @@ module DEBUGGER__
|
|
137
160
|
end
|
138
161
|
|
139
162
|
line = (line || 'quit').strip
|
163
|
+
send "command #{pid} #{@width} #{line}"
|
140
164
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
165
|
+
when /^ask (\d+) (.*)/
|
166
|
+
pid = $1
|
167
|
+
print $2
|
168
|
+
send "answer #{pid} #{gets || ''}"
|
145
169
|
|
146
|
-
send "command #{line}"
|
147
|
-
when /^ask (.*)/
|
148
|
-
print $1
|
149
|
-
send "answer #{gets || ''}"
|
150
170
|
when /^quit/
|
151
171
|
raise 'quit'
|
172
|
+
|
152
173
|
else
|
153
174
|
puts "(unknown) #{line.inspect}"
|
154
175
|
end
|
@@ -156,6 +177,8 @@ module DEBUGGER__
|
|
156
177
|
rescue
|
157
178
|
STDERR.puts "disconnected (#{$!})"
|
158
179
|
exit
|
180
|
+
ensure
|
181
|
+
deactivate
|
159
182
|
end
|
160
183
|
end
|
161
184
|
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
|
|
@@ -351,21 +371,54 @@ module DEBUGGER__
|
|
351
371
|
|
352
372
|
## Unix domain socket configuration
|
353
373
|
|
354
|
-
def self.
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
374
|
+
def self.check_dir_authority path
|
375
|
+
fs = File.stat(path)
|
376
|
+
|
377
|
+
unless (dir_uid = fs.uid) == (uid = Process.uid)
|
378
|
+
raise "#{path} uid is #{dir_uid}, but Process.uid is #{uid}"
|
379
|
+
end
|
380
|
+
unless (dir_mode = fs.mode) == 040700 # 4: dir, 7:rwx
|
381
|
+
raise "#{path}'s mode is #{dir_mode.to_s(8)} (should be 040700)"
|
382
|
+
end
|
383
|
+
|
384
|
+
path
|
385
|
+
end
|
386
|
+
|
387
|
+
def self.unix_domain_socket_tmpdir
|
388
|
+
require 'tmpdir'
|
389
|
+
|
390
|
+
if tmpdir = Dir.tmpdir
|
391
|
+
path = File.join(tmpdir, "ruby-debug-sock-#{Process.uid}")
|
392
|
+
|
393
|
+
unless File.exist?(path)
|
394
|
+
d = Dir.mktmpdir
|
395
|
+
File.rename(d, path)
|
396
|
+
end
|
397
|
+
|
398
|
+
check_dir_authority(path)
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
def self.unix_domain_socket_homedir
|
403
|
+
if home = ENV['HOME']
|
359
404
|
path = File.join(home, '.ruby-debug-sock')
|
360
405
|
|
361
|
-
|
362
|
-
when !File.exist?(path)
|
406
|
+
unless File.exist?(path)
|
363
407
|
Dir.mkdir(path, 0700)
|
364
|
-
when !File.directory?(path)
|
365
|
-
raise "#{path} is not a directory."
|
366
408
|
end
|
409
|
+
|
410
|
+
check_dir_authority(path)
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
def self.unix_domain_socket_dir
|
415
|
+
case
|
416
|
+
when path = CONFIG[:sock_dir]
|
417
|
+
when path = ENV['XDG_RUNTIME_DIR']
|
418
|
+
when path = unix_domain_socket_tmpdir
|
419
|
+
when path = unix_domain_socket_homedir
|
367
420
|
else
|
368
|
-
raise 'specify RUBY_DEBUG_SOCK_DIR environment variable
|
421
|
+
raise 'specify RUBY_DEBUG_SOCK_DIR environment variable.'
|
369
422
|
end
|
370
423
|
|
371
424
|
path
|