debug 1.2.4 → 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: a6251dbcd2eb75a8b4932a740fe0294da996c7bcaaaa965f42353144786b5c0a
4
- data.tar.gz: 328c4949a62eeb5277d8d6882c1a7da565b2c5aaa4c2fc5cf52850ca7e454240
3
+ metadata.gz: adddd814397fedb45de84db6ccb2dc49c3aefae141e73b156e3b87c29a3edf60
4
+ data.tar.gz: 0b0cb92d077f04ed9f7bfa1f79f56f35dc4dc9054f27ea3608d23c5f0d462274
5
5
  SHA512:
6
- metadata.gz: 7c8c83768d7d9eca50f18018dc9255a54234ee9c048d9885d54d46399e7bf9910ca87f85a9cd804108ec319ec985095016b00b1ab0d45a787fb55ef96b2a9483
7
- data.tar.gz: 24c87a5fbef8a8c1851ffea1b21c53613389d0c8fa46a3a205562aa2c98f6515ad863e97a5ee8857914a0363110ef277bc961b8d04902b0a5f537f133f6f18af
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/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'
data/lib/debug/client.rb CHANGED
@@ -21,6 +21,18 @@ module DEBUGGER__
21
21
  when 'list-socks'
22
22
  cleanup_unix_domain_sockets
23
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
24
36
  else
25
37
  raise "Unknown utility: #{name}"
26
38
  end
@@ -31,6 +43,7 @@ module DEBUGGER__
31
43
  if /(\d+)$/ =~ file
32
44
  begin
33
45
  Process.kill(0, $1.to_i)
46
+ rescue Errno::EPERM
34
47
  rescue Errno::ESRCH
35
48
  File.unlink(file)
36
49
  end
@@ -44,17 +57,15 @@ module DEBUGGER__
44
57
  end
45
58
 
46
59
  def initialize argv
60
+ @multi_process = false
61
+ @pid = nil
47
62
  @console = Console.new
48
63
 
49
64
  case argv.size
50
65
  when 0
51
66
  connect_unix
52
67
  when 1
53
- case arg = argv.shift
54
- when /-h/, /--help/
55
- help
56
- exit
57
- when /\A\d+\z/
68
+ if /\A\d+\z/ =~ (arg = argv.shift.strip)
58
69
  connect_tcp nil, arg.to_i
59
70
  else
60
71
  connect_unix arg
@@ -67,13 +78,22 @@ module DEBUGGER__
67
78
 
68
79
  @width = IO.console_size[1]
69
80
  @width = 80 if @width == 0
70
- @width_changed = false
71
81
 
72
82
  send "version: #{VERSION} width: #{@width} cookie: #{CONFIG[:cookie]}"
73
83
  end
74
84
 
85
+ def deactivate
86
+ @console.deactivate if @console
87
+ end
88
+
75
89
  def readline
76
- @console.readline "(rdbg:remote) "
90
+ if @multi_process
91
+ @console.readline "(rdbg:remote\##{@pid}) "
92
+ else
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
@@ -118,15 +138,19 @@ module DEBUGGER__
118
138
  }
119
139
  trap(:SIGWINCH){
120
140
  @width = IO.console_size[1]
121
- @width_changed = true
122
141
  }
123
142
 
124
143
  while line = @s.gets
125
144
  p recv: line if $VERBOSE
126
145
  case line
146
+
127
147
  when /^out (.*)/
128
148
  puts "#{$1}"
129
- when /^input/
149
+
150
+ when /^input (.+)/
151
+ pid = $1
152
+ @multi_process = true if @pid && @pid != pid
153
+ @pid = pid
130
154
  prev_trap = trap(:SIGINT, 'DEFAULT')
131
155
 
132
156
  begin
@@ -138,18 +162,16 @@ module DEBUGGER__
138
162
  end
139
163
 
140
164
  line = (line || 'quit').strip
165
+ send "command #{pid} #{@width} #{line}"
141
166
 
142
- if @width_changed
143
- @width_changed = false
144
- send "width #{@width}"
145
- end
167
+ when /^ask (\d+) (.*)/
168
+ pid = $1
169
+ print $2
170
+ send "answer #{pid} #{gets || ''}"
146
171
 
147
- send "command #{line}"
148
- when /^ask (.*)/
149
- print $1
150
- send "answer #{gets || ''}"
151
172
  when /^quit/
152
173
  raise 'quit'
174
+
153
175
  else
154
176
  puts "(unknown) #{line.inspect}"
155
177
  end
@@ -157,6 +179,8 @@ module DEBUGGER__
157
179
  rescue
158
180
  STDERR.puts "disconnected (#{$!})"
159
181
  exit
182
+ ensure
183
+ deactivate
160
184
  end
161
185
  end
162
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:'
data/lib/debug/console.rb CHANGED
@@ -31,6 +31,7 @@ module DEBUGGER__
31
31
  end if SIGWINCH_SUPPORTED
32
32
 
33
33
  def readline_setup prompt
34
+ load_history_if_not_loaded
34
35
  commands = DEBUGGER__.commands
35
36
 
36
37
  Reline.completion_proc = -> given do
@@ -87,40 +88,106 @@ module DEBUGGER__
87
88
  Reline.readmultiline(prompt, true){ true }
88
89
  end
89
90
 
91
+ def history
92
+ Reline::HISTORY
93
+ end
94
+
90
95
  rescue LoadError
91
- begin
92
- require 'readline.so'
96
+ begin
97
+ require 'readline.so'
98
+
99
+ def readline_setup
100
+ load_history_if_not_loaded
101
+ commands = DEBUGGER__.commands
102
+
103
+ Readline.completion_proc = proc{|given|
104
+ buff = Readline.line_buffer
105
+ Readline.completion_append_character= ' '
106
+
107
+ if /\s/ =~ buff # second parameters
108
+ given = File.expand_path(given + 'a').sub(/a\z/, '')
109
+ files = Dir.glob(given + '*')
110
+ if files.size == 1 && File.directory?(files.first)
111
+ Readline.completion_append_character= '/'
112
+ end
113
+ files
114
+ else
115
+ commands.keys.grep(/\A#{given}/)
116
+ end
117
+ }
118
+ end
93
119
 
94
- def readline_setup
95
- Readline.completion_proc = proc{|given|
96
- buff = Readline.line_buffer
97
- Readline.completion_append_character= ' '
120
+ def readline prompt
121
+ readline_setup
122
+ Readline.readline(prompt, true)
123
+ end
98
124
 
99
- if /\s/ =~ buff # second parameters
100
- given = File.expand_path(given + 'a').sub(/a\z/, '')
101
- files = Dir.glob(given + '*')
102
- if files.size == 1 && File.directory?(files.first)
103
- Readline.completion_append_character= '/'
104
- end
105
- files
106
- else
107
- DEBUGGER__.commands.keys.grep(/\A#{given}/)
108
- end
109
- }
125
+ def history
126
+ Readline::HISTORY
127
+ end
128
+
129
+ rescue LoadError
130
+ def readline prompt
131
+ print prompt
132
+ gets
133
+ end
134
+
135
+ def history
136
+ nil
137
+ end
110
138
  end
139
+ end
111
140
 
112
- def readline prompt
113
- readline_setup
114
- Readline.readline(prompt, true)
141
+ def history_file
142
+ CONFIG[:history_file] || File.expand_path("~/.rdbg_history")
143
+ end
144
+
145
+ FH = "# Today's OMIKUJI: "
146
+
147
+ def read_history_file
148
+ if history && File.exists?(path = history_file)
149
+ f = (['', 'DAI-', 'CHU-', 'SHO-'].map{|e| e+'KICHI'}+['KYO']).sample
150
+ ["#{FH}#{f}".dup] + File.readlines(path)
151
+ else
152
+ []
115
153
  end
154
+ end
116
155
 
117
- rescue LoadError
118
- def readline prompt
119
- print prompt
120
- gets
156
+ def initialize
157
+ @init_history_lines = nil
158
+ end
159
+
160
+ def load_history_if_not_loaded
161
+ return if @init_history_lines
162
+
163
+ @init_history_lines = load_history
164
+ end
165
+
166
+ def deactivate
167
+ if history && @init_history_lines
168
+ added_records = history.to_a[@init_history_lines .. -1]
169
+ path = history_file
170
+ max = CONFIG[:save_history] || 10_000
171
+
172
+ if !added_records.empty? && !path.empty?
173
+ orig_records = read_history_file
174
+ open(history_file, 'w'){|f|
175
+ (orig_records + added_records).last(max).each{|line|
176
+ if !line.start_with?(FH) && !line.strip.empty?
177
+ f.puts line.strip
178
+ end
179
+ }
180
+ }
181
+ end
121
182
  end
122
183
  end
184
+
185
+ def load_history
186
+ read_history_file.count{|line|
187
+ line.strip!
188
+ history << line unless line.empty?
189
+ }
123
190
  end
124
- end
191
+ end # class Console
125
192
  end
126
193
 
data/lib/debug/local.rb CHANGED
@@ -26,8 +26,11 @@ module DEBUGGER__
26
26
 
27
27
  def deactivate
28
28
  if SESSION.intercept_trap_sigint?
29
- trap(:SIGINT, SESSION.intercepted_sigint_cmd)
29
+ prev = SESSION.intercept_trap_sigint_end
30
+ trap(:SIGINT, prev)
30
31
  end
32
+
33
+ @console.deactivate
31
34
  end
32
35
 
33
36
  def width
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ return if defined?(::DEBUGGER__)
4
+
5
+ #
6
+ # put the following line in .bash_profile
7
+ # export RUBYOPT="-r .../debug/prelude $(RUBYOPT)"
8
+ #
9
+ module Kernel
10
+ def debugger(*a, up_level: 0, **kw)
11
+ begin
12
+ require_relative 'version'
13
+ cur_version = ::DEBUGGER__::VERSION
14
+ require_relative 'frame_info'
15
+
16
+ if !defined?(::DEBUGGER__::SO_VERSION) || ::DEBUGGER__::VERSION != ::DEBUGGER__::SO_VERSION
17
+ ::Object.send(:remove_const, :DEBUGGER__)
18
+ raise LoadError
19
+ end
20
+ require_relative 'session'
21
+ up_level += 1
22
+ rescue LoadError
23
+ $LOADED_FEATURES.delete_if{|e|
24
+ e.start_with?(__dir__) || e.end_with?('debug/debug.so')
25
+ }
26
+ require 'debug/session'
27
+ require 'debug/version'
28
+ ::DEBUGGER__.info "Can not activate debug #{cur_version} specified by debug/prelude.rb. Activate debug #{DEBUGGER__::VERSION} instead."
29
+ up_level += 1
30
+ end
31
+
32
+ ::DEBUGGER__::start no_sigint_hook: true, nonstop: true
33
+
34
+ begin
35
+ debugger(*a, up_level: up_level, **kw)
36
+ self
37
+ rescue ArgumentError # for 1.2.4 and earlier
38
+ debugger(*a, **kw)
39
+ self
40
+ end
41
+ end
42
+
43
+ alias b debugger if ENV['RUBY_DEBUG_B']
44
+ end
45
+
46
+ class Binding
47
+ alias break debugger
48
+ alias b debugger
49
+ end