debug 1.2.4 → 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: 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