debug 1.2.1 → 1.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 556965976e9db176b06e1997eb167cf5538ccd301ddb497ae629cfda01062fa3
4
- data.tar.gz: e709e60ef9b43b44a998362347b2b8d7e3d4cbddb4831cd43156d5ddc67dead8
3
+ metadata.gz: adddd814397fedb45de84db6ccb2dc49c3aefae141e73b156e3b87c29a3edf60
4
+ data.tar.gz: 0b0cb92d077f04ed9f7bfa1f79f56f35dc4dc9054f27ea3608d23c5f0d462274
5
5
  SHA512:
6
- metadata.gz: 9169efb00f3f9cebb0f9f21d2773e29d4c67edd7a4bb0b7330664080a15972cfe43199ae3c43e86424b2a6f94b83ce1fb8be1c208149cdd04f28c12f5d9f2842
7
- data.tar.gz: a56d82fb5beb82cd821639ae073d8f902aafbdfc762236ea6eb0b2d391cc1e121e541d16083b6b22ae5a8c73b2c2c2e49e54c39f37ac9d4c03d38210499398c8
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
- * VSCode/DAP integration ([VSCode rdbg Ruby Debugger - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=KoichiSasada.vscode-rdbg))
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
- * `RUBY_DEBUG_PARENT_ON_FORK` (`parent_on_fork`): Keep debugging parent process on fork (default: false)
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 Start remote debugging with opening the network port.
702
- If TCP/IP options are not given,
703
- a UNIX domain socket will be used.
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
- require "rake/extensiontask"
11
-
12
- task :build => :compile
13
-
14
- Rake::ExtensionTask.new("debug") do |ext|
15
- ext.lib_dir = "lib/debug"
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
@@ -1,2 +1,4 @@
1
1
  require 'mkmf'
2
+ require_relative '../../lib/debug/version'
3
+ File.write("debug_version.h", "#define RUBY_DEBUG_VERSION \"#{DEBUGGER__::VERSION}\"\n")
2
4
  create_makefile 'debug/debug'
@@ -437,7 +437,7 @@ module DEBUGGER__
437
437
  end
438
438
  end
439
439
 
440
- rescue ArgumentError => e
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 => e
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
- def initialize argv
17
- return util(argv) if String === argv
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
- case arg = argv.shift
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 readline
48
- @console.readline "(rdbg:remote) "
85
+ def deactivate
86
+ @console.deactivate if @console
49
87
  end
50
88
 
51
- def util name
52
- case name
53
- when 'gen-sockpath'
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
- raise "Unknown utility: #{name}"
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
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
- when /^input/
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
- if @width_changed
142
- @width_changed = false
143
- send "width #{@width}"
144
- end
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
- parent_on_fork: ['RUBY_DEBUG_PARENT_ON_FORK', "CONTROL: Keep debugging parent process on fork (default: false)", :bool],
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', "REMOTE: TCP/IP remote debugging: port"],
39
- host: ['RUBY_DEBUG_HOST', "REMOTE: TCP/IP remote debugging: host (localhost if not given)"],
40
- sock_path: ['RUBY_DEBUG_SOCK_PATH', "REMOTE: UNIX Domain Socket remote debugging: socket path"],
41
- sock_dir: ['RUBY_DEBUG_SOCK_DIR', "REMOTE: UNIX Domain Socket remote debugging: socket directory"],
42
- cookie: ['RUBY_DEBUG_COOKIE', "REMOTE: Cookie for negotiation"],
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 = self.config.dup
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
- 'If TCP/IP options are not given,',
260
- 'a UNIX domain socket will be used.') do
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.new(name)
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