debug 1.3.3 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Ruby](https://github.com/ruby/debug/actions/workflows/ruby.yml/badge.svg?branch=master)](https://github.com/ruby/debug/actions/workflows/ruby.yml?query=branch%3Amaster)
|
1
|
+
[![Ruby](https://github.com/ruby/debug/actions/workflows/ruby.yml/badge.svg?branch=master)](https://github.com/ruby/debug/actions/workflows/ruby.yml?query=branch%3Amaster) [![Protocol](https://github.com/ruby/debug/actions/workflows/protocol.yml/badge.svg)](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'
|