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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7831c2e401b4bf33ecd14f5cef5eeb1c1a0feb57037a162c00f6cc780975b4c6
4
- data.tar.gz: 182d55e56b662858b04e03336dd8bb4d0e15da8418b3aea137d05dcd02aa4ac0
3
+ metadata.gz: 948301b2d85d9acb8758ae20e63a60d0253dc1d1e1bf5c2ddc276abb39d12993
4
+ data.tar.gz: 2e6b7c89ee568710d52d3fcaff1ff5eb44db71c4e296e039a6f21f4e5de9b9ee
5
5
  SHA512:
6
- metadata.gz: dcf9f62fc4cf7f782238cd7b61137bde035047f6226eeac6cae639b28ada181862ee82ce146a1e33c6c08d80a8fc35ffe4a2cf24eda576e4792babbf8436ca88
7
- data.tar.gz: 1f66b3c18a14f1f337d010a8e9d29d6a0e0b1c4c92c976a87e0c2db265ff6a1259d31918e4c10525d16154f6a8f9fa694bcdbebbb081278b6ee488ae122f8713
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
- * 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/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
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
- 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,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 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
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
- when /^input/
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
- if @width_changed
142
- @width_changed = false
143
- send "width #{@width}"
144
- end
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
- 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
 
@@ -351,21 +371,54 @@ module DEBUGGER__
351
371
 
352
372
  ## Unix domain socket configuration
353
373
 
354
- def self.unix_domain_socket_dir
355
- case
356
- when path = CONFIG[:sock_dir]
357
- when path = ENV['XDG_RUNTIME_DIR']
358
- when home = ENV['HOME']
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
- case
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 for UNIX domain socket directory.'
421
+ raise 'specify RUBY_DEBUG_SOCK_DIR environment variable.'
369
422
  end
370
423
 
371
424
  path