debug 1.3.3 → 1.5.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 +4 -4
- data/CONTRIBUTING.md +163 -6
- data/Gemfile +1 -0
- data/README.md +42 -15
- data/Rakefile +5 -5
- data/debug.gemspec +6 -4
- data/ext/debug/debug.c +88 -1
- data/ext/debug/extconf.rb +11 -0
- data/lib/debug/breakpoint.rb +75 -36
- data/lib/debug/client.rb +65 -18
- data/lib/debug/color.rb +29 -19
- data/lib/debug/config.rb +6 -3
- data/lib/debug/console.rb +50 -15
- data/lib/debug/frame_info.rb +14 -20
- data/lib/debug/local.rb +1 -1
- data/lib/debug/prelude.rb +2 -2
- data/lib/debug/server.rb +100 -94
- data/lib/debug/server_cdp.rb +878 -160
- data/lib/debug/server_dap.rb +277 -81
- data/lib/debug/session.rb +327 -154
- data/lib/debug/source_repository.rb +90 -52
- data/lib/debug/thread_client.rb +149 -78
- data/lib/debug/tracer.rb +4 -10
- data/lib/debug/version.rb +1 -1
- data/misc/README.md.erb +16 -8
- metadata +4 -12
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -24
- data/.github/ISSUE_TEMPLATE/custom.md +0 -10
- data/.github/ISSUE_TEMPLATE/feature_request.md +0 -14
- data/.github/workflows/ruby.yml +0 -34
- data/.gitignore +0 -12
- data/bin/console +0 -14
- data/bin/gentest +0 -22
- data/bin/setup +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 121cdb1003971d234dbeb40878f693d06053fa32f28024c5d2a7c0e0fd6d3719
|
4
|
+
data.tar.gz: fd95c68d4bf99b38a83cef1a6851680bb9abb65d39fa9fc69a94d248295a5829
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4354a11670db6e0fd49e4b8151b268a08c7843c80ccd36b5c492cf5fabc7b42c6632939905b9912c81434f5513e36dac8378686b5d47c274248c523eea88a0c8
|
7
|
+
data.tar.gz: e22274473f567bed800c25d46a46d32adf263f070e8147cd71778ef9cbd95b8e239e2912b226892f032266a92322045a62e7f9c908f176e601a984e254acd2a7
|
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,161 @@ 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.
|
251
|
+
|
252
|
+
### Tests for DAP and CDP
|
253
|
+
|
254
|
+
Currently, there are 2 kinds of test frameworks for DAP and CDP.
|
255
|
+
|
256
|
+
1. Protocol-based tests
|
257
|
+
|
258
|
+
If you want to write protocol-based tests, you should use the test generator.
|
259
|
+
To run the test generator, you can enter `$ bin/gentest target.rb --open=vscode` in the terminal, VSCode will be executed.
|
260
|
+
Also, if you enter ``$ bin/gentest target.rb --open=chrome` there, Chrome will be executed.
|
261
|
+
If you need to modify existing tests, it is basically a good idea to regenerate them by the test generator instead of rewriting them directly.
|
262
|
+
Please refer to [the Microsoft "Debug Adapter Protocol" article](https://microsoft.github.io/debug-adapter-protocol/specification) to learn more about DAP formats.
|
263
|
+
Please refer to [Procol viewer for "Chrome DevTools Protocol"](https://chromedevtools.github.io/devtools-protocol/) to learn more about CDP formats.
|
264
|
+
|
265
|
+
2. High-level tests
|
266
|
+
|
267
|
+
High-level tests are designed to test both DAP and CDP for a single method.
|
268
|
+
You can write tests as follows:
|
269
|
+
**NOTE:** Use `req_terminate_debuggee` to finish debugging. You can't use any methods such as `req_continue`, `req_next` and so on.
|
270
|
+
|
271
|
+
```ruby
|
272
|
+
require_relative '../support/test_case'
|
273
|
+
module DEBUGGER__
|
274
|
+
class BreakTest < TestCase
|
275
|
+
# PROGRAM is the target script.
|
276
|
+
PROGRAM = <<~RUBY
|
277
|
+
1| module Foo
|
278
|
+
2| class Bar
|
279
|
+
3| def self.a
|
280
|
+
4| "hello"
|
281
|
+
5| end
|
282
|
+
6| end
|
283
|
+
7| Bar.a
|
284
|
+
8| bar = Bar.new
|
285
|
+
9| end
|
286
|
+
RUBY
|
287
|
+
|
288
|
+
def test_break1
|
289
|
+
run_protocol_scenario PROGRAM do # Start debugging with DAP and CDP
|
290
|
+
req_add_breakpoint 5 # Set a breakpoint on line 5.
|
291
|
+
req_add_breakpoint 8 # Set a breakpoint on line 8.
|
292
|
+
req_continue # Resume the program.
|
293
|
+
assert_line_num 5 # Check if debugger stops at line 5.
|
294
|
+
req_continue # Resume the program.
|
295
|
+
assert_line_num 8 # Check if debugger stops at line 8.
|
296
|
+
req_terminate_debuggee # Terminate debugging.
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
```
|
302
|
+
|
303
|
+
#### API
|
304
|
+
|
305
|
+
- run_protocol_scenario program, dap: true, cdp: true, &scenario
|
306
|
+
|
307
|
+
Execute debugging `program` with `&scenario`. If you want to test it only for DAP, you can write as follows:
|
308
|
+
|
309
|
+
`run_protocol_scenario program, cdp: false ...`
|
310
|
+
|
311
|
+
- req_add_breakpoint(lineno, path: temp_file_path, cond: nil)
|
312
|
+
|
313
|
+
Sends request to rdbg to add a breakpoint.
|
314
|
+
|
315
|
+
- req_delete_breakpoint bpnum
|
316
|
+
|
317
|
+
Sends request to rdbg to delete a breakpoint.
|
318
|
+
|
319
|
+
- req_set_exception_breakpoints
|
320
|
+
|
321
|
+
Sends request to rdbg to set exception breakpoints.
|
322
|
+
|
323
|
+
- req_continue
|
324
|
+
|
325
|
+
Sends request to rdbg to resume the program.
|
326
|
+
|
327
|
+
- req_step
|
328
|
+
|
329
|
+
Sends request to rdbg to step into next method.
|
330
|
+
|
331
|
+
- req_next
|
332
|
+
|
333
|
+
Sends request to rdbg to step over next method.
|
334
|
+
|
335
|
+
- req_finish
|
336
|
+
|
337
|
+
Sends request to rdbg to step out of current method.
|
338
|
+
|
339
|
+
- req_step_back
|
340
|
+
|
341
|
+
Sends request to rdbg to step back from current method.
|
342
|
+
|
343
|
+
- req_terminate_debuggee
|
344
|
+
|
345
|
+
Sends request to rdbg to terminate the debuggee.
|
346
|
+
|
347
|
+
- assert_reattach
|
348
|
+
|
349
|
+
Passes if reattaching to rdbg is successful.
|
350
|
+
|
351
|
+
- assert_hover_result(expected, expression: nil)
|
352
|
+
|
353
|
+
Passes if result of `expression` is equal to `expected`.
|
354
|
+
|
355
|
+
- assert_repl_result(expected, expression: nil)
|
356
|
+
|
357
|
+
Passes if result of `expression` is equal to `expected`.
|
358
|
+
|
359
|
+
- assert_watch_result(expected, expression: nil)
|
360
|
+
|
361
|
+
Passes if result of `expression` is equal to `expected`.
|
362
|
+
|
363
|
+
- assert_line_num(expected)
|
364
|
+
|
365
|
+
Passes if `expected` is equal to the location where debugger stops.
|
366
|
+
|
367
|
+
- assert_locals_result(expected)
|
368
|
+
|
369
|
+
Passes if all of `expected` local variable entries match the ones returned by debugger.
|
370
|
+
|
371
|
+
An variable entry looks like this: `{ name: "bar", value: "nil", type: "NilClass" }`.
|
372
|
+
|
373
|
+
Please note that both `value` and `type` need to be strings.
|
374
|
+
|
218
375
|
|
219
376
|
## To Update README
|
220
377
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
[](https://github.com/ruby/debug/actions/workflows/ruby.yml?query=branch%3Amaster)
|
1
|
+
[](https://github.com/ruby/debug/actions/workflows/ruby.yml?query=branch%3Amaster) [](https://github.com/ruby/debug/actions/workflows/protocol.yml)
|
2
2
|
|
3
3
|
# debug.rb
|
4
4
|
|
5
|
-
This library provides debugging functionality to Ruby.
|
5
|
+
This library provides debugging functionality to Ruby (MRI) 2.6 and later.
|
6
6
|
|
7
7
|
This debug.rb is replacement of traditional lib/debug.rb standard library which is implemented by `set_trace_func`.
|
8
8
|
New debug.rb has several advantages:
|
@@ -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
|
|
@@ -107,7 +113,7 @@ d => nil
|
|
107
113
|
5| binding.break
|
108
114
|
6| c = 3
|
109
115
|
7| d = 4
|
110
|
-
=> 8| binding.break # Again the program stops
|
116
|
+
=> 8| binding.break # Again the program stops here
|
111
117
|
9| p [a, b, c, d]
|
112
118
|
10|
|
113
119
|
11| __END__
|
@@ -346,12 +352,14 @@ 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
|
|
353
359
|
#### VSCode integration
|
354
360
|
|
361
|
+
([vscode-rdbg v0.0.9](https://marketplace.visualstudio.com/items?itemName=KoichiSasada.vscode-rdbg) or later is required)
|
362
|
+
|
355
363
|
If you don't run a debuggee Ruby process on VSCode, you can attach with VSCode later with the following steps.
|
356
364
|
|
357
365
|
`rdbg --open=vscode` opens the debug port and tries to invoke the VSCode (`code` command).
|
@@ -411,7 +419,7 @@ Note that you can attach with `rdbg --attach` and continue REPL debugging.
|
|
411
419
|
|
412
420
|
#### Chrome DevTool integration
|
413
421
|
|
414
|
-
With `rdbg --open=chrome` command will
|
422
|
+
With `rdbg --open=chrome` command will show the following message.
|
415
423
|
|
416
424
|
```
|
417
425
|
$ rdbg target.rb --open=chrome
|
@@ -427,7 +435,7 @@ Type `devtools://devtools/bundled/inspector.html?ws=127.0.0.1:43633` in the addr
|
|
427
435
|
|
428
436
|
Also `open chrome` command works like `open vscode`.
|
429
437
|
|
430
|
-
For more information about how to use Chrome debugging, you might want to read [here](https://developer.chrome.com/docs/devtools/)
|
438
|
+
For more information about how to use Chrome debugging, you might want to read [here](https://developer.chrome.com/docs/devtools/).
|
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>`
|
571
|
+
* break if the path matches to `<path>`. `<path>` can be a regexp with `/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>`
|
584
|
+
* stops if the exception is raised from a `<path>`. `<path>` can be a regexp with `/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>`
|
595
|
+
* stops if the path matches `<path>`. `<path>` can be a regexp with `/regexp/`.
|
569
596
|
* `del[ete]`
|
570
597
|
* delete all breakpoints.
|
571
598
|
* `del[ete] <bpnum>`
|
@@ -604,8 +631,8 @@ The `<...>` notation means the argument.
|
|
604
631
|
* Show information about accessible constants except toplevel constants.
|
605
632
|
* `i[nfo] g[lobal[s]]`
|
606
633
|
* Show information about global variables
|
607
|
-
* `i[nfo] ...
|
608
|
-
* Filter the output with
|
634
|
+
* `i[nfo] ... /regexp/`
|
635
|
+
* Filter the output with `/regexp/`.
|
609
636
|
* `i[nfo] th[read[s]]`
|
610
637
|
* Show all threads (same as `th[read]`).
|
611
638
|
* `o[utline]` or `ls`
|
@@ -656,8 +683,8 @@ The `<...>` notation means the argument.
|
|
656
683
|
* Add an exception tracer. It indicates raising exceptions.
|
657
684
|
* `trace object <expr>`
|
658
685
|
* Add an object tracer. It indicates that an object by `<expr>` is passed as a parameter or a receiver on method call.
|
659
|
-
* `trace ...
|
660
|
-
* Indicates only matched events to
|
686
|
+
* `trace ... /regexp/`
|
687
|
+
* Indicates only matched events to `/regexp/`.
|
661
688
|
* `trace ... into: <file>`
|
662
689
|
* Save trace information into: `<file>`.
|
663
690
|
* `trace off <num>`
|
data/Rakefile
CHANGED
@@ -2,8 +2,6 @@ require "bundler/gem_tasks"
|
|
2
2
|
require "rake/testtask"
|
3
3
|
|
4
4
|
Rake::TestTask.new(:test) do |t|
|
5
|
-
t.libs << "test"
|
6
|
-
t.libs << "lib"
|
7
5
|
t.test_files = FileList["test/**/*_test.rb"]
|
8
6
|
end
|
9
7
|
|
@@ -17,7 +15,6 @@ begin
|
|
17
15
|
rescue LoadError
|
18
16
|
end
|
19
17
|
|
20
|
-
|
21
18
|
task :default => [:clobber, :compile, 'README.md', :test]
|
22
19
|
|
23
20
|
file 'README.md' => ['lib/debug/session.rb', 'lib/debug/config.rb',
|
@@ -28,7 +25,10 @@ file 'README.md' => ['lib/debug/session.rb', 'lib/debug/config.rb',
|
|
28
25
|
puts 'README.md is updated.'
|
29
26
|
end
|
30
27
|
|
31
|
-
task :
|
32
|
-
|
28
|
+
task :test_protocol do
|
29
|
+
ENV['RUBY_DEBUG_PROTOCOL_TEST'] = '1'
|
33
30
|
end
|
34
31
|
|
32
|
+
Rake::TestTask.new(:test_protocol) do |t|
|
33
|
+
t.test_files = FileList["test/protocol/*_test.rb"]
|
34
|
+
end
|
data/debug.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.email = ["ko1@atdot.net"]
|
8
8
|
|
9
9
|
spec.summary = %q{Debugging functionality for Ruby}
|
10
|
-
spec.description = %q{Debugging functionality for Ruby. This is completely rewritten debug.rb which was contained by the
|
10
|
+
spec.description = %q{Debugging functionality for Ruby. This is completely rewritten debug.rb which was contained by the ancient Ruby versions.}
|
11
11
|
spec.homepage = "https://github.com/ruby/debug"
|
12
12
|
spec.licenses = ["Ruby", "BSD-2-Clause"]
|
13
13
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
|
@@ -17,11 +17,13 @@ Gem::Specification.new do |spec|
|
|
17
17
|
|
18
18
|
# Specify which files should be added to the gem when it is released.
|
19
19
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
20
|
-
spec.files
|
21
|
-
`git ls-files -z`.split("\x0").reject
|
20
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
21
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
22
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
23
|
+
end
|
22
24
|
end
|
23
25
|
spec.bindir = "exe"
|
24
|
-
spec.executables = spec.files.grep(%r{
|
26
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
25
27
|
spec.require_paths = ["lib"]
|
26
28
|
spec.extensions = ['ext/debug/extconf.rb']
|
27
29
|
|
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
|
@@ -115,11 +118,82 @@ create_method_added_tracker(VALUE self)
|
|
115
118
|
return rb_tracepoint_new(0, RUBY_EVENT_CALL, method_added_tracker, NULL);
|
116
119
|
}
|
117
120
|
|
121
|
+
// iseq
|
122
|
+
|
123
|
+
const struct rb_iseq *rb_iseqw_to_iseq(VALUE iseqw);
|
124
|
+
|
125
|
+
#ifdef HAVE_RB_ISEQ_TYPE
|
126
|
+
VALUE rb_iseq_type(const struct rb_iseq *);
|
127
|
+
|
128
|
+
static VALUE
|
129
|
+
iseq_type(VALUE iseqw)
|
130
|
+
{
|
131
|
+
const struct rb_iseq *iseq = rb_iseqw_to_iseq(iseqw);
|
132
|
+
return rb_iseq_type(iseq);
|
133
|
+
}
|
134
|
+
#endif
|
135
|
+
|
136
|
+
#ifdef HAVE_RB_ISEQ_PARAMETERS
|
137
|
+
VALUE rb_iseq_parameters(const struct rb_iseq *, int is_proc);
|
138
|
+
|
139
|
+
static VALUE
|
140
|
+
iseq_parameters_symbols(VALUE iseqw)
|
141
|
+
{
|
142
|
+
const struct rb_iseq *iseq = rb_iseqw_to_iseq(iseqw);
|
143
|
+
VALUE params = rb_iseq_parameters(iseq, 0);
|
144
|
+
VALUE ary = rb_ary_new();
|
145
|
+
|
146
|
+
static VALUE sym_ast, sym_astast, sym_amp;
|
147
|
+
|
148
|
+
if (sym_ast == 0) {
|
149
|
+
sym_ast = ID2SYM(rb_intern("*"));
|
150
|
+
sym_astast = ID2SYM(rb_intern("**"));
|
151
|
+
sym_amp = ID2SYM(rb_intern("&"));
|
152
|
+
}
|
153
|
+
|
154
|
+
for (long i=0; i<RARRAY_LEN(params); i++) {
|
155
|
+
VALUE e = RARRAY_AREF(params, i);
|
156
|
+
if (RARRAY_LEN(e) == 2) {
|
157
|
+
VALUE sym = RARRAY_AREF(e, 1);
|
158
|
+
if (sym != sym_ast &&
|
159
|
+
sym != sym_astast &&
|
160
|
+
sym != sym_amp) rb_ary_push(ary, RARRAY_AREF(e, 1));
|
161
|
+
}
|
162
|
+
}
|
163
|
+
|
164
|
+
return ary;
|
165
|
+
}
|
166
|
+
#endif
|
167
|
+
|
168
|
+
#ifdef HAVE_RB_ISEQ_CODE_LOCATION
|
169
|
+
void rb_iseq_code_location(const struct rb_iseq *, int *first_lineno, int *first_column, int *last_lineno, int *last_column);
|
170
|
+
|
171
|
+
static VALUE
|
172
|
+
iseq_first_line(VALUE iseqw)
|
173
|
+
{
|
174
|
+
const struct rb_iseq *iseq = rb_iseqw_to_iseq(iseqw);
|
175
|
+
int line;
|
176
|
+
rb_iseq_code_location(iseq, &line, NULL, NULL, NULL);
|
177
|
+
return INT2NUM(line);
|
178
|
+
}
|
179
|
+
|
180
|
+
static VALUE
|
181
|
+
iseq_last_line(VALUE iseqw)
|
182
|
+
{
|
183
|
+
const struct rb_iseq *iseq = rb_iseqw_to_iseq(iseqw);
|
184
|
+
int line;
|
185
|
+
rb_iseq_code_location(iseq, NULL, NULL, &line, NULL);
|
186
|
+
return INT2NUM(line);
|
187
|
+
}
|
188
|
+
#endif
|
189
|
+
|
118
190
|
void Init_iseq_collector(void);
|
119
191
|
|
120
192
|
void
|
121
193
|
Init_debug(void)
|
122
194
|
{
|
195
|
+
VALUE rb_mRubyVM = rb_const_get(rb_cObject, rb_intern("RubyVM"));
|
196
|
+
VALUE rb_cISeq = rb_const_get(rb_mRubyVM, rb_intern("InstructionSequence"));
|
123
197
|
rb_mDebugger = rb_const_get(rb_cObject, rb_intern("DEBUGGER__"));
|
124
198
|
rb_cFrameInfo = rb_const_get(rb_mDebugger, rb_intern("FrameInfo"));
|
125
199
|
|
@@ -131,5 +205,18 @@ Init_debug(void)
|
|
131
205
|
rb_define_singleton_method(rb_mDebugger, "frame_depth", frame_depth, 0);
|
132
206
|
rb_define_singleton_method(rb_mDebugger, "create_method_added_tracker", create_method_added_tracker, 0);
|
133
207
|
rb_define_const(rb_mDebugger, "SO_VERSION", rb_str_new2(RUBY_DEBUG_VERSION));
|
208
|
+
|
209
|
+
// iseq
|
210
|
+
#ifdef HAVE_RB_ISEQ_TYPE
|
211
|
+
rb_define_method(rb_cISeq, "type", iseq_type, 0);
|
212
|
+
#endif
|
213
|
+
#ifdef HAVE_RB_ISEQ_PARAMETERS
|
214
|
+
rb_define_method(rb_cISeq, "parameters_symbols", iseq_parameters_symbols, 0);
|
215
|
+
#endif
|
216
|
+
#ifdef HAVE_RB_ISEQ_CODE_LOCATION
|
217
|
+
rb_define_method(rb_cISeq, "first_line", iseq_first_line, 0);
|
218
|
+
rb_define_method(rb_cISeq, "last_line", iseq_last_line, 0);
|
219
|
+
#endif
|
220
|
+
|
134
221
|
Init_iseq_collector();
|
135
222
|
}
|
data/ext/debug/extconf.rb
CHANGED
@@ -1,4 +1,15 @@
|
|
1
1
|
require 'mkmf'
|
2
2
|
require_relative '../../lib/debug/version'
|
3
3
|
File.write("debug_version.h", "#define RUBY_DEBUG_VERSION \"#{DEBUGGER__::VERSION}\"\n")
|
4
|
+
|
5
|
+
have_func "rb_iseq_parameters(NULL, 0)",
|
6
|
+
[["VALUE rb_iseq_parameters(void *, int is_proc);"]]
|
7
|
+
|
8
|
+
have_func "rb_iseq_code_location(NULL, NULL, NULL, NULL, NULL)",
|
9
|
+
[["void rb_iseq_code_location(void *, int *first_lineno, int *first_column, int *last_lineno, int *last_column);"]]
|
10
|
+
|
11
|
+
# from Ruby 3.1
|
12
|
+
have_func "rb_iseq_type(NULL)",
|
13
|
+
[["VALUE rb_iseq_type(void *);"]]
|
14
|
+
|
4
15
|
create_makefile 'debug/debug'
|