debug 1.3.4 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/pull_request_template.md +9 -0
- data/CONTRIBUTING.md +39 -6
- data/README.md +34 -7
- data/bin/gentest +12 -4
- data/ext/debug/debug.c +4 -1
- data/lib/debug/breakpoint.rb +61 -11
- data/lib/debug/client.rb +57 -16
- data/lib/debug/color.rb +29 -19
- data/lib/debug/config.rb +6 -3
- data/lib/debug/console.rb +17 -3
- data/lib/debug/frame_info.rb +11 -16
- data/lib/debug/prelude.rb +2 -2
- data/lib/debug/server.rb +45 -77
- data/lib/debug/server_cdp.rb +590 -93
- data/lib/debug/server_dap.rb +231 -53
- data/lib/debug/session.rb +114 -52
- data/lib/debug/source_repository.rb +4 -6
- data/lib/debug/thread_client.rb +67 -48
- data/lib/debug/tracer.rb +1 -1
- data/lib/debug/version.rb +1 -1
- data/misc/README.md.erb +12 -4
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a62295065b9bb4f9d498a21b32ea122ab680fd1e1b9794368ac2385858abf844
|
4
|
+
data.tar.gz: 0dc6f9aeb1ff23a47e0c399ee32ac80953821520cc52b0c4e27e30d7600a67bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 144d16fc2b8e377d7d25df0b09f088492647b76de2ffc1a841e09967caed2678f28fbaf24747fc351fd7e7d7c0d107cd39245ca0c8eff41547bce4f2ab35a8c3
|
7
|
+
data.tar.gz: 4e62e36b0fe72a2c1ce8e1dd44e6bae646e06b0d4d8d07072db595f908d00595252e35525a9ba1fde09a53f9a57781165c73e63d8eaa8a59a5e93219bd4c9ed5
|
@@ -0,0 +1,9 @@
|
|
1
|
+
Thanks for your Pull Request 🎉
|
2
|
+
|
3
|
+
**Please follow these instructions to help us review it more efficiently:**
|
4
|
+
|
5
|
+
- Add references of related issues/PRs in the description if available.
|
6
|
+
- If you're updating the readme file, make sure you followed [the instruction here](https://github.com/ruby/debug/blob/master/CONTRIBUTING.md#to-update-readme).
|
7
|
+
|
8
|
+
## Description
|
9
|
+
Describe your changes:
|
data/CONTRIBUTING.md
CHANGED
@@ -26,11 +26,17 @@ $ ruby test/debug/bp_test.rb -h # to see all the test options
|
|
26
26
|
```
|
27
27
|
|
28
28
|
## Generate Tests
|
29
|
+
|
29
30
|
There is a test generator in `debug.rb` project to make it easier to write tests.
|
31
|
+
|
30
32
|
### Quickstart
|
31
|
-
|
33
|
+
|
34
|
+
This section shows you how to create test file by test generator. For more advanced information on creating tests, please take a look at [gentest options](#gentest-options). (You can also check by `$bin/gentest -h`)
|
35
|
+
|
32
36
|
#### 1. Create a target file for debuggee.
|
37
|
+
|
33
38
|
Let's say, we created `target.rb` which is located in top level directory of debugger.
|
39
|
+
|
34
40
|
```ruby
|
35
41
|
module Foo
|
36
42
|
class Bar
|
@@ -42,11 +48,15 @@ module Foo
|
|
42
48
|
bar = Bar.new
|
43
49
|
end
|
44
50
|
```
|
51
|
+
|
45
52
|
#### 2. Run `gentest` as shown in the example below.
|
53
|
+
|
46
54
|
```shell
|
47
55
|
$ bin/gentest target.rb
|
48
56
|
```
|
57
|
+
|
49
58
|
#### 3. Debugger will be executed. You can type any debug commands.
|
59
|
+
|
50
60
|
```shell
|
51
61
|
$ bin/gentest target.rb
|
52
62
|
DEBUGGER: Session start (pid: 11139)
|
@@ -119,8 +129,11 @@ created: /Users/naotto/workspace/debug/test/tool/../debug/foo_test.rb
|
|
119
129
|
class: FooTest
|
120
130
|
method: test_1629720194
|
121
131
|
```
|
132
|
+
|
122
133
|
#### 4. The test file will be created as `test/debug/foo_test.rb`.
|
134
|
+
|
123
135
|
If the file already exists, **only method** will be added to it.
|
136
|
+
|
124
137
|
```ruby
|
125
138
|
# frozen_string_literal: true
|
126
139
|
|
@@ -204,17 +217,37 @@ end
|
|
204
217
|
```
|
205
218
|
|
206
219
|
#### gentest options
|
220
|
+
|
207
221
|
You can get more information about `gentest` here.
|
208
222
|
|
209
|
-
The default method name is `test_#{some integer numbers}`, the class name is `FooTest`, and the file name will be `foo_test.rb`.
|
223
|
+
The default method name is `test_#{some integer numbers}`, the class name is `FooTest#{some integer numbers}`, and the file name will be `foo_test.rb`.
|
210
224
|
The following table shows examples of the gentest options.
|
211
225
|
|
212
226
|
| Command | Description | File | Class | Method |
|
213
227
|
| --- | --- | --- | --- | --- |
|
214
|
-
| `$ bin/gentest target.rb` | Run without any options | `foo_test.rb` | `FooTest
|
215
|
-
| `$ bin/gentest target.rb
|
216
|
-
| `$ bin/gentest target.rb -
|
217
|
-
| `$ bin/gentest target.rb -
|
228
|
+
| `$ bin/gentest target.rb` | Run without any options | `foo_test.rb` | `FooTest...` | `test_...` |
|
229
|
+
| `$ bin/gentest target.rb --open=vscode` | Run the debugger with VScode | `foo_test.rb` | `FooTest...` | `test_...` |
|
230
|
+
| `$ bin/gentest target.rb -c step` | Specify the class name | `step_test.rb` | `StepTest...` | `test_...` |
|
231
|
+
| `$ bin/gentest target.rb -m test_step` | Specify the method name | `foo_test.rb` | `FooTest...` | `test_step` |
|
232
|
+
| `$ bin/gentest target.rb -c step -m test_step` | Specify the class name and the method name | `step_test.rb` | `StepTest...` | `test_step` |
|
233
|
+
|
234
|
+
### Assertions
|
235
|
+
|
236
|
+
- assert_line_num(expected)
|
237
|
+
|
238
|
+
Passes if `expected` is equal to the location where debugger stops.
|
239
|
+
|
240
|
+
- assert_line_text(text)
|
241
|
+
|
242
|
+
Passes if `text` is included in the last debugger log.
|
243
|
+
|
244
|
+
- assert_no_line_text(text)
|
245
|
+
|
246
|
+
Passes if `text` is not included in the last debugger log.
|
247
|
+
|
248
|
+
- assert_debuggee_line_text(text)
|
249
|
+
|
250
|
+
Passes if `text` is included in the debuggee log.
|
218
251
|
|
219
252
|
## To Update README
|
220
253
|
|
data/README.md
CHANGED
@@ -60,8 +60,14 @@ There are several options for (1) and (2). Please choose your favorite way.
|
|
60
60
|
|
61
61
|
### Modify source code with [`binding.break`](#bindingbreak-method) (similar to `binding.pry` or `binding.irb`)
|
62
62
|
|
63
|
-
If you can modify the source code, you can use the debugger by adding `require 'debug'`
|
64
|
-
|
63
|
+
If you can modify the source code, you can use the debugger by adding `require 'debug'` at the top of your program and putting [`binding.break`](#bindingbreak-method) method into lines where you want to stop as breakpoints like `binding.pry` and `binding.irb`.
|
64
|
+
|
65
|
+
You can also use its 2 aliases in the same way:
|
66
|
+
|
67
|
+
- `binding.b`
|
68
|
+
- `debugger`
|
69
|
+
|
70
|
+
After that, run the program as usual and you will enter the debug console at breakpoints you inserted.
|
65
71
|
|
66
72
|
The following example shows the demonstration of [`binding.break`](#bindingbreak-method).
|
67
73
|
|
@@ -346,7 +352,7 @@ You can attach with external debugger frontend with VSCode and Chrome.
|
|
346
352
|
$ rdbg --open=[frontend] target.rb
|
347
353
|
```
|
348
354
|
|
349
|
-
will open a debug port and `[
|
355
|
+
will open a debug port and `[frontend]` can attach to the port.
|
350
356
|
|
351
357
|
Also `open` command allows opening the debug port.
|
352
358
|
|
@@ -427,7 +433,9 @@ Type `devtools://devtools/bundled/inspector.html?ws=127.0.0.1:43633` in the addr
|
|
427
433
|
|
428
434
|
Also `open chrome` command works like `open vscode`.
|
429
435
|
|
430
|
-
For more information about how to use Chrome debugging, you might want to read [here](https://developer.chrome.com/docs/devtools/)
|
436
|
+
For more information about how to use Chrome debugging, you might want to read [here](https://developer.chrome.com/docs/devtools/).
|
437
|
+
|
438
|
+
Note: If you want to maximize Chrome DevTools, click [Toggle Device Toolbar](https://developer.chrome.com/docs/devtools/device-mode/#viewport).
|
431
439
|
|
432
440
|
## Configuration
|
433
441
|
|
@@ -479,6 +487,7 @@ config set no_color true
|
|
479
487
|
* `RUBY_DEBUG_SOCK_DIR` (`sock_dir`): UNIX Domain Socket remote debugging: socket directory
|
480
488
|
* `RUBY_DEBUG_COOKIE` (`cookie`): Cookie for negotiation
|
481
489
|
* `RUBY_DEBUG_OPEN_FRONTEND` (`open_frontend`): frontend used by open command (vscode, chrome, default: rdbg).
|
490
|
+
* `RUBY_DEBUG_CHROME_PATH` (`chrome_path`): Platform dependent path of Chrome (For more information, See [here](https://github.com/ruby/debug/pull/334/files#diff-5fc3d0a901379a95bc111b86cf0090b03f857edfd0b99a0c1537e26735698453R55-R64))
|
482
491
|
|
483
492
|
* OBSOLETE
|
484
493
|
* `RUBY_DEBUG_PARENT_ON_FORK` (`parent_on_fork`): Keep debugging parent process on fork (default: false)
|
@@ -525,7 +534,7 @@ The `<...>` notation means the argument.
|
|
525
534
|
* `fin[ish]`
|
526
535
|
* Finish this frame. Resume the program until the current frame is finished.
|
527
536
|
* `fin[ish] <n>`
|
528
|
-
* Finish frames
|
537
|
+
* Finish `<n>`th frames.
|
529
538
|
* `c[ontinue]`
|
530
539
|
* Resume the program.
|
531
540
|
* `q[uit]` or `Ctrl-D`
|
@@ -533,11 +542,11 @@ The `<...>` notation means the argument.
|
|
533
542
|
* `q[uit]!`
|
534
543
|
* Same as q[uit] but without the confirmation prompt.
|
535
544
|
* `kill`
|
536
|
-
* Stop the debuggee process with `
|
545
|
+
* Stop the debuggee process with `Kernel#exit!`.
|
537
546
|
* `kill!`
|
538
547
|
* Same as kill but without the confirmation prompt.
|
539
548
|
* `sigint`
|
540
|
-
* Execute SIGINT handler
|
549
|
+
* Execute SIGINT handler registered by the debuggee.
|
541
550
|
* Note that this command should be used just after stop by `SIGINT`.
|
542
551
|
|
543
552
|
### Breakpoint
|
@@ -558,14 +567,32 @@ The `<...>` notation means the argument.
|
|
558
567
|
* break and run `<command>` before stopping.
|
559
568
|
* `b[reak] ... do: <command>`
|
560
569
|
* break and run `<command>`, and continue.
|
570
|
+
* `b[reak] ... path: <path_regexp>`
|
571
|
+
* break if the triggering event's path matches <path_regexp>.
|
561
572
|
* `b[reak] if: <expr>`
|
562
573
|
* break if: `<expr>` is true at any lines.
|
563
574
|
* Note that this feature is super slow.
|
564
575
|
* `catch <Error>`
|
565
576
|
* Set breakpoint on raising `<Error>`.
|
577
|
+
* `catch ... if: <expr>`
|
578
|
+
* stops only if `<expr>` is true as well.
|
579
|
+
* `catch ... pre: <command>`
|
580
|
+
* runs `<command>` before stopping.
|
581
|
+
* `catch ... do: <command>`
|
582
|
+
* stops and run `<command>`, and continue.
|
583
|
+
* `catch ... path: <path_regexp>`
|
584
|
+
* stops if the exception is raised from a path that matches <path_regexp>.
|
566
585
|
* `watch @ivar`
|
567
586
|
* Stop the execution when the result of current scope's `@ivar` is changed.
|
568
587
|
* Note that this feature is super slow.
|
588
|
+
* `watch ... if: <expr>`
|
589
|
+
* stops only if `<expr>` is true as well.
|
590
|
+
* `watch ... pre: <command>`
|
591
|
+
* runs `<command>` before stopping.
|
592
|
+
* `watch ... do: <command>`
|
593
|
+
* stops and run `<command>`, and continue.
|
594
|
+
* `watch ... path: <path_regexp>`
|
595
|
+
* stops if the triggering event's path matches <path_regexp>.
|
569
596
|
* `del[ete]`
|
570
597
|
* delete all breakpoints.
|
571
598
|
* `del[ete] <bpnum>`
|
data/bin/gentest
CHANGED
@@ -4,19 +4,27 @@ require 'optparse'
|
|
4
4
|
|
5
5
|
require_relative '../test/tool/test_builder'
|
6
6
|
|
7
|
-
|
7
|
+
options = {}
|
8
8
|
|
9
9
|
OptionParser.new do |opt|
|
10
10
|
opt.banner = 'Usage: bin/gentest [file] [option]'
|
11
11
|
opt.on('-m METHOD', 'Method name in the test file') do |m|
|
12
|
-
|
12
|
+
options[:method] = m
|
13
13
|
end
|
14
14
|
opt.on('-c CLASS', 'Class name in the test file') do |c|
|
15
|
-
|
15
|
+
options[:class] = c
|
16
|
+
end
|
17
|
+
opt.on('--open=FRONTEND', 'Start remote debugging with opening the network port.',
|
18
|
+
'Currently, only vscode is supported.') do |f|
|
19
|
+
options[:open] = f.downcase
|
16
20
|
end
|
17
21
|
opt.parse!(ARGV)
|
18
22
|
end
|
19
23
|
|
20
24
|
exit if ARGV.empty?
|
21
25
|
|
22
|
-
|
26
|
+
if options[:open] == 'vscode'
|
27
|
+
DEBUGGER__::DAPTestBuilder.new(ARGV, options[:method], options[:class]).start
|
28
|
+
else
|
29
|
+
DEBUGGER__::LocalTestBuilder.new(ARGV, options[:method], options[:class]).start
|
30
|
+
end
|
data/ext/debug/debug.c
CHANGED
@@ -32,7 +32,10 @@ di_entry(VALUE loc, VALUE self, VALUE binding, VALUE iseq, VALUE klass, VALUE de
|
|
32
32
|
// :show_line, :local_variables
|
33
33
|
Qnil,
|
34
34
|
// :_local_variables, :_callee # for recorder
|
35
|
-
Qnil, Qnil
|
35
|
+
Qnil, Qnil,
|
36
|
+
// :dupped_binding
|
37
|
+
Qnil
|
38
|
+
);
|
36
39
|
}
|
37
40
|
|
38
41
|
static int
|
data/lib/debug/breakpoint.rb
CHANGED
@@ -4,6 +4,8 @@ require_relative 'color'
|
|
4
4
|
|
5
5
|
module DEBUGGER__
|
6
6
|
class Breakpoint
|
7
|
+
include SkipPathHelper
|
8
|
+
|
7
9
|
attr_reader :key
|
8
10
|
|
9
11
|
def initialize do_enable = true
|
@@ -23,6 +25,10 @@ module DEBUGGER__
|
|
23
25
|
nil
|
24
26
|
end
|
25
27
|
|
28
|
+
def oneshot?
|
29
|
+
defined?(@oneshot) && @oneshot
|
30
|
+
end
|
31
|
+
|
26
32
|
def setup
|
27
33
|
raise "not implemented..."
|
28
34
|
end
|
@@ -75,6 +81,14 @@ module DEBUGGER__
|
|
75
81
|
false
|
76
82
|
end
|
77
83
|
|
84
|
+
def skip_path?(path)
|
85
|
+
if @path
|
86
|
+
!path.match?(@path)
|
87
|
+
else
|
88
|
+
super
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
78
92
|
include Color
|
79
93
|
|
80
94
|
def generate_label(name)
|
@@ -87,6 +101,28 @@ module DEBUGGER__
|
|
87
101
|
TracePoint.new(:line){}.enable{}
|
88
102
|
end
|
89
103
|
|
104
|
+
class ISeqBreakpoint < Breakpoint
|
105
|
+
def initialize iseq, events, oneshot: false
|
106
|
+
@events = events
|
107
|
+
@iseq = iseq
|
108
|
+
@oneshot = oneshot
|
109
|
+
@key = [:iseq, @iseq.path, @iseq.first_lineno].freeze
|
110
|
+
|
111
|
+
super()
|
112
|
+
end
|
113
|
+
|
114
|
+
def setup
|
115
|
+
@tp = TracePoint.new(*@events) do |tp|
|
116
|
+
delete if @oneshot
|
117
|
+
suspend
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def enable
|
122
|
+
@tp.enable(target: @iseq)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
90
126
|
class LineBreakpoint < Breakpoint
|
91
127
|
attr_reader :path, :line, :iseq
|
92
128
|
|
@@ -235,24 +271,25 @@ module DEBUGGER__
|
|
235
271
|
|
236
272
|
class CatchBreakpoint < Breakpoint
|
237
273
|
attr_reader :last_exc
|
238
|
-
include SkipPathHelper
|
239
274
|
|
240
|
-
def initialize pat, cond: nil, command: nil
|
275
|
+
def initialize pat, cond: nil, command: nil, path: nil
|
241
276
|
@pat = pat.freeze
|
242
277
|
@key = [:catch, @pat].freeze
|
243
278
|
@last_exc = nil
|
244
279
|
|
245
280
|
@cond = cond
|
246
281
|
@command = command
|
282
|
+
@path = path
|
247
283
|
|
248
284
|
super()
|
249
285
|
end
|
250
286
|
|
251
287
|
def setup
|
252
288
|
@tp = TracePoint.new(:raise){|tp|
|
253
|
-
next if skip_path?(tp.path)
|
254
289
|
exc = tp.raised_exception
|
255
290
|
next if SystemExit === exc
|
291
|
+
next if skip_path?(tp.path)
|
292
|
+
|
256
293
|
next if !safe_eval(tp.binding, @cond) if @cond
|
257
294
|
should_suspend = false
|
258
295
|
|
@@ -277,9 +314,10 @@ module DEBUGGER__
|
|
277
314
|
end
|
278
315
|
|
279
316
|
class CheckBreakpoint < Breakpoint
|
280
|
-
def initialize expr
|
317
|
+
def initialize expr, path
|
281
318
|
@expr = expr.freeze
|
282
319
|
@key = [:check, @expr].freeze
|
320
|
+
@path = path
|
283
321
|
|
284
322
|
super()
|
285
323
|
end
|
@@ -289,6 +327,7 @@ module DEBUGGER__
|
|
289
327
|
next if tp.path.start_with? __dir__
|
290
328
|
next if tp.path.start_with? '<internal:'
|
291
329
|
next if ThreadClient.current.management?
|
330
|
+
next if skip_path?(tp.path)
|
292
331
|
|
293
332
|
if safe_eval tp.binding, @expr
|
294
333
|
suspend
|
@@ -302,22 +341,29 @@ module DEBUGGER__
|
|
302
341
|
end
|
303
342
|
|
304
343
|
class WatchIVarBreakpoint < Breakpoint
|
305
|
-
def initialize ivar, object, current
|
344
|
+
def initialize ivar, object, current, cond: nil, command: nil, path: nil
|
306
345
|
@ivar = ivar.to_sym
|
307
346
|
@object = object
|
308
|
-
@key = [:watch, @ivar].freeze
|
347
|
+
@key = [:watch, object.object_id, @ivar].freeze
|
309
348
|
|
310
349
|
@current = current
|
350
|
+
|
351
|
+
@cond = cond
|
352
|
+
@command = command
|
353
|
+
@path = path
|
311
354
|
super()
|
312
355
|
end
|
313
356
|
|
314
|
-
def watch_eval
|
357
|
+
def watch_eval(tp)
|
315
358
|
result = @object.instance_variable_get(@ivar)
|
316
359
|
if result != @current
|
317
360
|
begin
|
318
361
|
@prev = @current
|
319
362
|
@current = result
|
320
|
-
|
363
|
+
|
364
|
+
if (@cond.nil? || @object.instance_eval(@cond)) && !skip_path?(tp.path)
|
365
|
+
suspend
|
366
|
+
end
|
321
367
|
ensure
|
322
368
|
remove_instance_variable(:@prev)
|
323
369
|
end
|
@@ -331,7 +377,7 @@ module DEBUGGER__
|
|
331
377
|
next if tp.path.start_with? __dir__
|
332
378
|
next if tp.path.start_with? '<internal:'
|
333
379
|
|
334
|
-
watch_eval
|
380
|
+
watch_eval(tp)
|
335
381
|
}
|
336
382
|
end
|
337
383
|
|
@@ -349,7 +395,7 @@ module DEBUGGER__
|
|
349
395
|
class MethodBreakpoint < Breakpoint
|
350
396
|
attr_reader :sig_method_name, :method
|
351
397
|
|
352
|
-
def initialize b, klass_name, op, method_name, cond: nil, command: nil
|
398
|
+
def initialize b, klass_name, op, method_name, cond: nil, command: nil, path: nil
|
353
399
|
@sig_klass_name = klass_name
|
354
400
|
@sig_op = op
|
355
401
|
@sig_method_name = method_name
|
@@ -361,6 +407,7 @@ module DEBUGGER__
|
|
361
407
|
@cond = cond
|
362
408
|
@cond_class = nil
|
363
409
|
@command = command
|
410
|
+
@path = path
|
364
411
|
@key = "#{klass_name}#{op}#{method_name}".freeze
|
365
412
|
|
366
413
|
super(false)
|
@@ -370,7 +417,10 @@ module DEBUGGER__
|
|
370
417
|
@tp = TracePoint.new(:call){|tp|
|
371
418
|
next if !safe_eval(tp.binding, @cond) if @cond
|
372
419
|
next if @cond_class && !tp.self.kind_of?(@cond_class)
|
373
|
-
|
420
|
+
|
421
|
+
caller_location = caller_locations(2, 1).first.to_s
|
422
|
+
next if caller_location.start_with?(__dir__)
|
423
|
+
next if skip_path?(caller_location)
|
374
424
|
|
375
425
|
suspend
|
376
426
|
}
|
data/lib/debug/client.rb
CHANGED
@@ -21,20 +21,56 @@ module DEBUGGER__
|
|
21
21
|
when 'list-socks'
|
22
22
|
cleanup_unix_domain_sockets
|
23
23
|
puts list_connections
|
24
|
-
when '
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
24
|
+
when 'setup-autoload'
|
25
|
+
setup_autoload
|
26
|
+
else
|
27
|
+
abort "Unknown utility: #{name}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def working_shell_type
|
32
|
+
shell = `ps -p #{Process.ppid} -o 'args='`
|
33
|
+
case shell
|
34
|
+
when /bash/
|
35
|
+
:bash
|
36
|
+
when /fish/
|
37
|
+
:fish
|
38
|
+
when /csh/
|
39
|
+
:csh
|
40
|
+
when /zsh/
|
41
|
+
:szh
|
42
|
+
when /dash/
|
43
|
+
:dash
|
36
44
|
else
|
37
|
-
|
45
|
+
:unknown
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def setup_autoload
|
50
|
+
prelude_path = File.join(__dir__, 'prelude.rb')
|
51
|
+
|
52
|
+
case shell = working_shell_type
|
53
|
+
when :bash, :zsh
|
54
|
+
puts <<~EOS
|
55
|
+
# add the following lines in your ~/.#{shell}_profile
|
56
|
+
|
57
|
+
if test -s #{prelude_path} ; then
|
58
|
+
export RUBYOPT='-r #{prelude_path}'
|
59
|
+
fi
|
60
|
+
|
61
|
+
# Add `Kernel#bb` method which is alias of `Kernel#debugger`
|
62
|
+
# export RUBY_DEBUG_BB=1
|
63
|
+
EOS
|
64
|
+
|
65
|
+
when :fish
|
66
|
+
puts <<~EOS
|
67
|
+
# add the following lines in your ~/.config/fish/config.fish
|
68
|
+
set -x RUBYOPT "-r #{__dir__}/prelude" $RUBYOPT
|
69
|
+
EOS
|
70
|
+
|
71
|
+
else
|
72
|
+
puts "# Sorry that your shell is not supported yet.",
|
73
|
+
"# Please use the content in #{prelude_path} as a reference and modify your login script accordingly."
|
38
74
|
end
|
39
75
|
end
|
40
76
|
|
@@ -134,9 +170,14 @@ module DEBUGGER__
|
|
134
170
|
trap(:SIGINT){
|
135
171
|
send "pause"
|
136
172
|
}
|
137
|
-
|
138
|
-
|
139
|
-
|
173
|
+
|
174
|
+
begin
|
175
|
+
trap(:SIGWINCH){
|
176
|
+
@width = IO.console_size[1]
|
177
|
+
}
|
178
|
+
rescue ArgumentError => e
|
179
|
+
@width = 80
|
180
|
+
end
|
140
181
|
|
141
182
|
while line = @s.gets
|
142
183
|
p recv: line if $VERBOSE
|
data/lib/debug/color.rb
CHANGED
@@ -48,33 +48,29 @@ module DEBUGGER__
|
|
48
48
|
|
49
49
|
if defined? IRB::ColorPrinter.pp
|
50
50
|
def color_pp obj, width
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
with_inspection_error_guard do
|
52
|
+
if !CONFIG[:no_color]
|
53
|
+
IRB::ColorPrinter.pp(obj, "".dup, width)
|
54
|
+
else
|
55
|
+
obj.pretty_inspect
|
56
|
+
end
|
55
57
|
end
|
56
58
|
end
|
57
59
|
else
|
58
60
|
def color_pp obj, width
|
59
|
-
|
61
|
+
with_inspection_error_guard do
|
62
|
+
obj.pretty_inspect
|
63
|
+
end
|
60
64
|
end
|
61
65
|
end
|
62
66
|
|
63
67
|
def colored_inspect obj, width: SESSION.width, no_color: false
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
err_msg = "#{ex.inspect} rescued during inspection"
|
71
|
-
string_result = obj.to_s rescue nil
|
72
|
-
|
73
|
-
# don't colorize the string here because it's not from user's application
|
74
|
-
if string_result
|
75
|
-
%Q{"#{string_result}" from #to_s because #{err_msg}}
|
76
|
-
else
|
77
|
-
err_msg
|
68
|
+
with_inspection_error_guard do
|
69
|
+
if !no_color
|
70
|
+
color_pp obj, width
|
71
|
+
else
|
72
|
+
obj.pretty_inspect
|
73
|
+
end
|
78
74
|
end
|
79
75
|
end
|
80
76
|
|
@@ -109,5 +105,19 @@ module DEBUGGER__
|
|
109
105
|
def colorize_dim(str)
|
110
106
|
colorize(str, [:DIM])
|
111
107
|
end
|
108
|
+
|
109
|
+
def with_inspection_error_guard
|
110
|
+
yield
|
111
|
+
rescue Exception => ex
|
112
|
+
err_msg = "#{ex.inspect} rescued during inspection"
|
113
|
+
string_result = obj.to_s rescue nil
|
114
|
+
|
115
|
+
# don't colorize the string here because it's not from user's application
|
116
|
+
if string_result
|
117
|
+
%Q{"#{string_result}" from #to_s because #{err_msg}}
|
118
|
+
else
|
119
|
+
err_msg
|
120
|
+
end
|
121
|
+
end
|
112
122
|
end
|
113
123
|
end
|
data/lib/debug/config.rb
CHANGED
@@ -43,20 +43,23 @@ module DEBUGGER__
|
|
43
43
|
sock_dir: ['RUBY_DEBUG_SOCK_DIR', "REMOTE: UNIX Domain Socket remote debugging: socket directory"],
|
44
44
|
cookie: ['RUBY_DEBUG_COOKIE', "REMOTE: Cookie for negotiation"],
|
45
45
|
open_frontend: ['RUBY_DEBUG_OPEN_FRONTEND',"REMOTE: frontend used by open command (vscode, chrome, default: rdbg)."],
|
46
|
+
chrome_path: ['RUBY_DEBUG_CHROME_PATH', "REMOTE: Platform dependent path of Chrome (For more information, See [here](https://github.com/ruby/debug/pull/334/files#diff-5fc3d0a901379a95bc111b86cf0090b03f857edfd0b99a0c1537e26735698453R55-R64))"],
|
46
47
|
|
47
48
|
# obsolete
|
48
49
|
parent_on_fork: ['RUBY_DEBUG_PARENT_ON_FORK', "OBSOLETE: Keep debugging parent process on fork (default: false)", :bool],
|
49
50
|
}.freeze
|
50
51
|
|
51
|
-
CONFIG_MAP = CONFIG_SET.map{|k, (ev,
|
52
|
+
CONFIG_MAP = CONFIG_SET.map{|k, (ev, _)| [k, ev]}.to_h.freeze
|
52
53
|
|
53
54
|
class Config
|
55
|
+
@config = nil
|
56
|
+
|
54
57
|
def self.config
|
55
58
|
@config
|
56
59
|
end
|
57
60
|
|
58
61
|
def initialize argv
|
59
|
-
if self.class.
|
62
|
+
if self.class.config
|
60
63
|
raise 'Can not make multiple configurations in one process'
|
61
64
|
end
|
62
65
|
|
@@ -480,7 +483,7 @@ module DEBUGGER__
|
|
480
483
|
self.helps.each{|cat, cmds|
|
481
484
|
r << "### #{cat}"
|
482
485
|
r << ''
|
483
|
-
cmds.each{|
|
486
|
+
cmds.each{|_, desc|
|
484
487
|
r << desc
|
485
488
|
}
|
486
489
|
r << ''
|
data/lib/debug/console.rb
CHANGED
@@ -34,6 +34,12 @@ module DEBUGGER__
|
|
34
34
|
load_history_if_not_loaded
|
35
35
|
commands = DEBUGGER__.commands
|
36
36
|
|
37
|
+
prev_completion_proc = Reline.completion_proc
|
38
|
+
prev_output_modifier_proc = Reline.output_modifier_proc
|
39
|
+
prev_prompt_proc = Reline.prompt_proc
|
40
|
+
|
41
|
+
Reline.prompt_proc = nil
|
42
|
+
|
37
43
|
Reline.completion_proc = -> given do
|
38
44
|
buff = Reline.line_buffer
|
39
45
|
Reline.completion_append_character= ' '
|
@@ -72,6 +78,13 @@ module DEBUGGER__
|
|
72
78
|
colorize_code(buff.chomp) + colorize(" # ruby", [:DIM])
|
73
79
|
end
|
74
80
|
end
|
81
|
+
|
82
|
+
yield
|
83
|
+
|
84
|
+
ensure
|
85
|
+
Reline.completion_proc = prev_completion_proc
|
86
|
+
Reline.output_modifier_proc = prev_output_modifier_proc
|
87
|
+
Reline.prompt_proc = prev_prompt_proc
|
75
88
|
end
|
76
89
|
|
77
90
|
private def get_command line
|
@@ -84,8 +97,9 @@ module DEBUGGER__
|
|
84
97
|
end
|
85
98
|
|
86
99
|
def readline prompt
|
87
|
-
readline_setup prompt
|
88
|
-
|
100
|
+
readline_setup prompt do
|
101
|
+
Reline.readmultiline(prompt, true){ true }
|
102
|
+
end
|
89
103
|
end
|
90
104
|
|
91
105
|
def history
|
@@ -145,7 +159,7 @@ module DEBUGGER__
|
|
145
159
|
FH = "# Today's OMIKUJI: "
|
146
160
|
|
147
161
|
def read_history_file
|
148
|
-
if history && File.
|
162
|
+
if history && File.exist?(path = history_file)
|
149
163
|
f = (['', 'DAI-', 'CHU-', 'SHO-'].map{|e| e+'KICHI'}+['KYO']).sample
|
150
164
|
["#{FH}#{f}".dup] + File.readlines(path)
|
151
165
|
else
|