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 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