debug 1.0.0.beta4 → 1.0.0.beta5
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/.github/workflows/ruby.yml +34 -0
- data/.gitignore +1 -0
- data/CONTRIBUTING.md +48 -0
- data/Gemfile +1 -1
- data/README.md +72 -37
- data/debug.gemspec +2 -0
- data/exe/rdbg +8 -1
- data/ext/debug/debug.c +9 -8
- data/lib/debug/breakpoint.rb +71 -24
- data/lib/debug/client.rb +49 -6
- data/lib/debug/color.rb +70 -0
- data/lib/debug/config.rb +39 -5
- data/lib/debug/console.rb +8 -1
- data/lib/debug/frame_info.rb +61 -30
- data/lib/debug/open.rb +2 -0
- data/lib/debug/run.rb +2 -0
- data/lib/debug/server.rb +72 -19
- data/lib/debug/server_dap.rb +605 -0
- data/lib/debug/session.rb +181 -86
- data/lib/debug/source_repository.rb +53 -33
- data/lib/debug/test_console.rb +0 -0
- data/lib/debug/thread_client.rb +91 -23
- data/lib/debug/version.rb +1 -1
- data/misc/README.md.erb +51 -28
- metadata +21 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '039bd2cbfdb3a67bbd91603b077a4f4784235fb0c7b48721a4b9f27b493231c6'
|
4
|
+
data.tar.gz: f9605d076dff9d8571e70245baa5c2e97c2377cc7f92ee627cbc1f051361217b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f222a8b1ec58fd6f5264e61ee8613e6ed229c9ebff73c6b4904c4c6c2bded0d625b776fb510b23dec57636cf576a68d471f0b91d7b01d36f8baad741ff64fd38
|
7
|
+
data.tar.gz: 152431ba38203334bbf1c7449ff36a6d49f5116aaa78c017ca5ffa6d695ca87be06bc011822d0bbd325e15c46504385adf4ef94e74ebd37f97468f049da910e8
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: Ruby
|
9
|
+
|
10
|
+
on:
|
11
|
+
push:
|
12
|
+
branches: [ master ]
|
13
|
+
pull_request:
|
14
|
+
branches: [ master ]
|
15
|
+
|
16
|
+
jobs:
|
17
|
+
test:
|
18
|
+
|
19
|
+
runs-on: ubuntu-latest
|
20
|
+
strategy:
|
21
|
+
matrix:
|
22
|
+
ruby-version: ['2.6', '2.7', '3.0', 'head', 'debug']
|
23
|
+
|
24
|
+
steps:
|
25
|
+
- uses: actions/checkout@v2
|
26
|
+
- name: Set up Ruby
|
27
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
28
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
29
|
+
uses: ruby/setup-ruby@v1
|
30
|
+
with:
|
31
|
+
ruby-version: ${{ matrix.ruby-version }}
|
32
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
33
|
+
- name: Run tests
|
34
|
+
run: bundle exec rake
|
data/.gitignore
CHANGED
data/CONTRIBUTING.md
CHANGED
@@ -1,3 +1,51 @@
|
|
1
|
+
## Set Up a Development Environment
|
2
|
+
|
3
|
+
1. `$ git clone git@github.com:ruby/debug.git`
|
4
|
+
2. `$ bundle install`
|
5
|
+
3. `$ rake` - this will
|
6
|
+
- Compile the C extension locally (which can also be done solely with `rake compile`).
|
7
|
+
- Run tests.
|
8
|
+
- Re-generate `README.md`.
|
9
|
+
|
10
|
+
If you spot any problem, please open an issue.
|
11
|
+
|
12
|
+
## Run Tests
|
13
|
+
|
14
|
+
### Run all tests
|
15
|
+
|
16
|
+
```bash
|
17
|
+
$ rake test
|
18
|
+
# or
|
19
|
+
$ ruby bin/test-unit.rb
|
20
|
+
```
|
21
|
+
|
22
|
+
### Run specific test(s)
|
23
|
+
|
24
|
+
|
25
|
+
```bash
|
26
|
+
$ ruby test/debug/bp_test.rb # run all tests in the specified file
|
27
|
+
$ ruby test/debug/bp_test.rb -h # to see all the test options
|
28
|
+
```
|
29
|
+
|
30
|
+
## To Update README
|
31
|
+
|
32
|
+
This project generates `README.md` from the template `misc/README.md.erb`
|
33
|
+
|
34
|
+
So **do not** directly update `README.md`. Instead, you should update the template's source and run
|
35
|
+
|
36
|
+
```bash
|
37
|
+
$ rake
|
38
|
+
```
|
39
|
+
|
40
|
+
to reflect the changes on `README.md`.
|
41
|
+
|
42
|
+
|
43
|
+
### When to re-generate `README.md`
|
44
|
+
|
45
|
+
- After updating `misc/README.md.erb`.
|
46
|
+
- After updating `rdbg` executable's options.
|
47
|
+
- After updating comments of debugger's commands.
|
48
|
+
|
1
49
|
## Manually Test Your Changes
|
2
50
|
|
3
51
|
You can manually test your changes with a simple Ruby script + a line of command. The following example will help you check:
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
[](https://github.com/ruby/debug/actions/workflows/ruby.yml?query=branch%3Amaster)
|
2
|
+
|
1
3
|
# debug.rb
|
2
4
|
|
3
5
|
This library provides debugging functionality to Ruby.
|
@@ -49,28 +51,33 @@ To use debugging feature, you can have 3 ways.
|
|
49
51
|
|
50
52
|
### Local debug console
|
51
53
|
|
54
|
+
#### (1) Use `rdbg` command
|
55
|
+
|
52
56
|
```
|
53
|
-
# (1) Use `rdbg` command
|
54
57
|
$ rdbg target.rb
|
55
58
|
$ rdbg -- -r foo -e expr # -- is required to make clear rdbg options and ruby's options
|
59
|
+
```
|
56
60
|
|
57
|
-
|
61
|
+
#### (2) Use `-r debug/run` command line option
|
58
62
|
|
63
|
+
```
|
59
64
|
$ ruby -r debug/run target.rb
|
65
|
+
```
|
60
66
|
|
61
|
-
|
67
|
+
#### (3) Write `require 'debug...'` in .rb files
|
62
68
|
|
63
|
-
|
69
|
+
```ruby
|
70
|
+
# target.rb
|
64
71
|
require 'debug/run' # start the debug console
|
65
|
-
... rest of program ...
|
66
72
|
|
67
73
|
# or
|
68
74
|
|
69
|
-
$ cat target.rb
|
70
75
|
require 'debug/session' # introduce the functionality
|
71
76
|
DEBUGGER__.console # and start the debug console
|
72
|
-
... rest of program ...
|
77
|
+
# ... rest of program ...
|
78
|
+
```
|
73
79
|
|
80
|
+
```
|
74
81
|
$ ruby target.rb
|
75
82
|
```
|
76
83
|
|
@@ -144,33 +151,36 @@ $ rdbg ~/src/rb/target.rb
|
|
144
151
|
|
145
152
|
### Remote debug (1) UNIX domain socket
|
146
153
|
|
154
|
+
#### (1) Use `rdbg` command
|
155
|
+
|
147
156
|
```
|
148
|
-
# (1) Use `rdbg` command
|
149
157
|
$ rdbg --open target.rb # or rdbg -O target.rb for shorthand
|
150
158
|
Debugger can attach via UNIX domain socket (/home/ko1/.ruby-debug-sock/ruby-debug-ko1-5042)
|
151
|
-
|
159
|
+
```
|
152
160
|
|
153
|
-
|
161
|
+
#### (2) Use `-r debug/open` command line option
|
154
162
|
|
163
|
+
```
|
155
164
|
$ ruby -r debug/open target.rb
|
156
165
|
Debugger can attach via UNIX domain socket (/home/ko1/.ruby-debug-sock/ruby-debug-ko1-5042)
|
157
|
-
|
166
|
+
```
|
158
167
|
|
159
|
-
|
160
|
-
|
168
|
+
#### (3) Write `require 'debug/open'` in .rb files
|
169
|
+
|
170
|
+
```ruby
|
171
|
+
# target.rb
|
161
172
|
require 'debug/open' # open the debugger entry point by UNIX domain socket.
|
162
|
-
...
|
163
173
|
|
164
174
|
# or
|
165
175
|
|
166
|
-
$ cat target.rb
|
167
176
|
require 'debug/server' # introduce remote debugging feature
|
168
177
|
DEBUGGER__.open # open the debugger entry point by UNIX domain socket.
|
169
178
|
# or DEBUGGER__.open_unix to specify UNIX domain socket.
|
179
|
+
```
|
170
180
|
|
181
|
+
```
|
171
182
|
$ ruby target.rb
|
172
183
|
Debugger can attach via UNIX domain socket (/home/ko1/.ruby-debug-sock/ruby-debug-ko1-5042)
|
173
|
-
...
|
174
184
|
```
|
175
185
|
|
176
186
|
It runs target.rb and accept debugger connection within UNIX domain socket.
|
@@ -234,40 +244,49 @@ The socket file is located at
|
|
234
244
|
|
235
245
|
You can open the TCP/IP port instead of using UNIX domain socket.
|
236
246
|
|
247
|
+
#### (1) Use `rdbg` command
|
248
|
+
|
237
249
|
```
|
238
|
-
# (1) Use `rdbg` command
|
239
250
|
$ rdbg -O --port=12345 target.rb
|
240
251
|
# or
|
241
252
|
$ rdbg --open --port=12345 target.rb
|
242
253
|
Debugger can attach via TCP/IP (localhost:12345)
|
243
|
-
|
254
|
+
```
|
255
|
+
|
256
|
+
#### (2) Use `-r debug/open` command line option
|
244
257
|
|
245
|
-
# (2) Use `-r debug/open` command line option
|
246
258
|
|
259
|
+
```
|
247
260
|
$ RUBY_DEBUG_PORT=12345 ruby -r debug/open target.rb
|
248
261
|
Debugger can attach via TCP/IP (localhost:12345)
|
249
|
-
|
262
|
+
```
|
250
263
|
|
251
|
-
|
252
|
-
|
264
|
+
#### (3) Write `require 'debug/open'` in .rb files
|
265
|
+
|
266
|
+
```ruby
|
267
|
+
# target.rb
|
253
268
|
require 'debug/open' # open the debugger entry point.
|
254
|
-
|
269
|
+
```
|
255
270
|
|
256
|
-
|
271
|
+
and run with environment variable RUBY_DEBUG_PORT
|
272
|
+
|
273
|
+
```
|
257
274
|
$ RUBY_DEBUG_PORT=12345 ruby target.rb
|
258
275
|
Debugger can attach via TCP/IP (localhost:12345)
|
259
|
-
|
276
|
+
```
|
260
277
|
|
261
|
-
|
278
|
+
or
|
262
279
|
|
263
|
-
|
280
|
+
```ruby
|
281
|
+
# target.rb
|
264
282
|
require 'debug/server' # introduce remote debugging feature
|
265
283
|
DEBUGGER__.open(port: 12345)
|
266
284
|
# or DEBUGGER__.open_tcp(port: 12345)
|
285
|
+
```
|
267
286
|
|
287
|
+
```
|
268
288
|
$ ruby target.rb
|
269
289
|
Debugger can attach via TCP/IP (localhost:12345)
|
270
|
-
...
|
271
290
|
```
|
272
291
|
|
273
292
|
You can also specify the host with the `RUBY_DEBUG_HOST` environment variable. And also `DEBUGGER__.open` method accepts a `host:` keyword parameter. If the host is not given, `localhost` will be used.
|
@@ -296,10 +315,10 @@ You can control debuggee's behavior with environment variables:
|
|
296
315
|
* `RUBY_DEBUG_COMMANDS`: Debug commands invoked at the first stop. Commands should be separated by ';;'.
|
297
316
|
* `RUBY_DEBUG_SHOW_SRC_LINES`: Show n lines source code on breakpoint (default: 10 lines).
|
298
317
|
* `RUBY_DEBUG_SHOW_FRAMES`: Show n frames on breakpoint (default: 2 frames).
|
299
|
-
|
300
318
|
* Remote debugging
|
301
319
|
* `RUBY_DEBUG_PORT`: TCP/IP remote debugging: port to open.
|
302
320
|
* `RUBY_DEBUG_HOST`: TCP/IP remote debugging: host (localhost if not given) to open.
|
321
|
+
* `RUBY_DEBUG_SOCK_PATH`: UNIX Domain Socket remote debugging: socket path to open.
|
303
322
|
* `RUBY_DEBUG_SOCK_DIR`: UNIX Domain Socket remote debugging: socket directory to open.
|
304
323
|
|
305
324
|
## Debug command on the debug console
|
@@ -350,8 +369,8 @@ The `<...>` notation means the argument.
|
|
350
369
|
* Note that this feature is super slow.
|
351
370
|
* `catch <Error>`
|
352
371
|
* Set breakpoint on raising `<Error>`.
|
353
|
-
* `watch
|
354
|
-
* Stop the execution when the result of
|
372
|
+
* `watch @ivar`
|
373
|
+
* Stop the execution when the result of current scope's `@ivar` is changed.
|
355
374
|
* Note that this feature is super slow.
|
356
375
|
* `del[ete]`
|
357
376
|
* delete all breakpoints.
|
@@ -377,7 +396,7 @@ The `<...>` notation means the argument.
|
|
377
396
|
* `i[nfo]`, `i[nfo] l[ocal[s]]`
|
378
397
|
* Show information about the current frame (local variables)
|
379
398
|
* It includes `self` as `%self` and a return value as `%return`.
|
380
|
-
* `i[nfo] th[read[s]]
|
399
|
+
* `i[nfo] th[read[s]]`
|
381
400
|
* Show all threads (same as `th[read]`).
|
382
401
|
* `display`
|
383
402
|
* Show display setting.
|
@@ -434,13 +453,16 @@ exe/rdbg [options] -- [debuggee options]
|
|
434
453
|
|
435
454
|
Debug console mode:
|
436
455
|
-n, --nonstop Do not stop at the beginning of the script.
|
437
|
-
-e
|
438
|
-
-
|
456
|
+
-e COMMAND execute debug command at the beginning of the script.
|
457
|
+
-x, --init-script=FILE execute debug command in the FILE.
|
458
|
+
|
459
|
+
-O, --open Start remote debugging with opening the network port.
|
439
460
|
If TCP/IP options are not given,
|
440
461
|
a UNIX domain socket will be used.
|
441
|
-
--sock-path=
|
442
|
-
--port=
|
443
|
-
--host=
|
462
|
+
--sock-path=SOCK_PATH UNIX Doman socket path
|
463
|
+
--port=PORT Listening TCP/IP port
|
464
|
+
--host=HOST Listening TCP/IP host
|
465
|
+
--cookie=COOKIE Set a cookie for connection
|
444
466
|
|
445
467
|
Debug console mode runs Ruby program with the debug console.
|
446
468
|
|
@@ -462,6 +484,15 @@ Attach mode:
|
|
462
484
|
'rdbg -A port' tries to connect to localhost:port via TCP/IP.
|
463
485
|
'rdbg -A host port' tries to connect to host:port via TCP/IP.
|
464
486
|
|
487
|
+
Other options:
|
488
|
+
-h, --help Print help
|
489
|
+
-c, --command Command mode (first argument is command name)
|
490
|
+
--util=NAME Utility mode (used by tools)
|
491
|
+
|
492
|
+
NOTE
|
493
|
+
All messages communicated between a debugger and a debuggee are *NOT* encrypted.
|
494
|
+
Please use the remote debugging feature carefully.
|
495
|
+
|
465
496
|
```
|
466
497
|
|
467
498
|
# Contributing
|
@@ -469,3 +500,7 @@ Attach mode:
|
|
469
500
|
Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/debug.
|
470
501
|
|
471
502
|
Please also check the [contributing guideline](/CONTRIBUTING.md).
|
503
|
+
|
504
|
+
# Acknowledgement
|
505
|
+
|
506
|
+
* Some tests are based on [deivid-rodriguez/byebug: Debugging in Ruby 2](https://github.com/deivid-rodriguez/byebug)
|
data/debug.gemspec
CHANGED
@@ -24,4 +24,6 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
25
|
spec.require_paths = ["lib"]
|
26
26
|
spec.extensions = ['ext/debug/extconf.rb']
|
27
|
+
|
28
|
+
spec.add_dependency "irb" # for its color_printer class, which was added after 1.3
|
27
29
|
end
|
data/exe/rdbg
CHANGED
@@ -15,11 +15,18 @@ when :start
|
|
15
15
|
end
|
16
16
|
|
17
17
|
::DEBUGGER__.config_to_env(config)
|
18
|
-
|
18
|
+
|
19
|
+
cmd = config[:command] ? ARGV.shift : RbConfig.ruby
|
20
|
+
exec({'RUBYOPT' => "-I#{File.expand_path(File.dirname(__dir__))}/lib -r #{start_mode}"},
|
21
|
+
cmd, *ARGV)
|
19
22
|
|
20
23
|
when :attach
|
21
24
|
require_relative "../lib/debug/client"
|
22
25
|
|
26
|
+
config.each{|k, v|
|
27
|
+
DEBUGGER__::CONFIG[k] = v
|
28
|
+
}
|
29
|
+
|
23
30
|
begin
|
24
31
|
if ARGV.empty? && config[:port]
|
25
32
|
connect [config[:host], config[:port]].compact
|
data/ext/debug/debug.c
CHANGED
@@ -22,7 +22,7 @@ static VALUE rb_cFrameInfo;
|
|
22
22
|
static VALUE
|
23
23
|
di_entry(VALUE loc, VALUE self, VALUE binding, VALUE iseq, VALUE klass, VALUE depth)
|
24
24
|
{
|
25
|
-
return rb_struct_new(rb_cFrameInfo, loc, self, binding, iseq, klass, depth, Qnil, Qnil, Qnil);
|
25
|
+
return rb_struct_new(rb_cFrameInfo, loc, self, binding, iseq, klass, depth, Qnil, Qnil, Qnil, Qnil, Qnil);
|
26
26
|
}
|
27
27
|
|
28
28
|
static int
|
@@ -49,6 +49,7 @@ di_body(const rb_debug_inspector_t *dc, void *ptr)
|
|
49
49
|
long i;
|
50
50
|
|
51
51
|
for (i=1; i<len; i++) {
|
52
|
+
VALUE loc, e;
|
52
53
|
VALUE iseq = rb_debug_inspector_frame_iseq_get(dc, i);
|
53
54
|
|
54
55
|
if (!NIL_P(iseq)) {
|
@@ -56,13 +57,13 @@ di_body(const rb_debug_inspector_t *dc, void *ptr)
|
|
56
57
|
if (!NIL_P(path) && str_start_with(path, skip_path_prefix)) continue;
|
57
58
|
}
|
58
59
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
60
|
+
loc = RARRAY_AREF(locs, i);
|
61
|
+
e = di_entry(loc,
|
62
|
+
rb_debug_inspector_frame_self_get(dc, i),
|
63
|
+
rb_debug_inspector_frame_binding_get(dc, i),
|
64
|
+
iseq,
|
65
|
+
rb_debug_inspector_frame_class_get(dc, i),
|
66
|
+
INT2FIX(len - i));
|
66
67
|
rb_ary_push(ary, e);
|
67
68
|
}
|
68
69
|
|
data/lib/debug/breakpoint.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative 'color'
|
2
|
+
|
1
3
|
module DEBUGGER__
|
2
4
|
class Breakpoint
|
3
5
|
attr_reader :key
|
@@ -55,9 +57,24 @@ module DEBUGGER__
|
|
55
57
|
""
|
56
58
|
end
|
57
59
|
end
|
60
|
+
|
61
|
+
def description
|
62
|
+
to_s
|
63
|
+
end
|
64
|
+
|
65
|
+
class << self
|
66
|
+
include Color
|
67
|
+
|
68
|
+
def generate_label(name)
|
69
|
+
colorize(" BP - #{name} ", [:YELLOW, :BOLD, :REVERSE])
|
70
|
+
end
|
71
|
+
end
|
58
72
|
end
|
59
73
|
|
60
74
|
class LineBreakpoint < Breakpoint
|
75
|
+
LABEL = generate_label("Line")
|
76
|
+
PENDING_LABEL = generate_label("Line (pending)")
|
77
|
+
|
61
78
|
attr_reader :path, :line, :iseq
|
62
79
|
|
63
80
|
def initialize path, line, cond: nil, oneshot: false, hook_call: true
|
@@ -186,9 +203,9 @@ module DEBUGGER__
|
|
186
203
|
oneshot = @oneshot ? " (oneshot)" : ""
|
187
204
|
|
188
205
|
if @iseq
|
189
|
-
"
|
206
|
+
"#{LABEL} #{@path}:#{@line} (#{@type})#{oneshot}" + super
|
190
207
|
else
|
191
|
-
"
|
208
|
+
"#{PENDING_LABEL} #{@path}:#{@line}#{oneshot}" + super
|
192
209
|
end
|
193
210
|
end
|
194
211
|
|
@@ -198,9 +215,13 @@ module DEBUGGER__
|
|
198
215
|
end
|
199
216
|
|
200
217
|
class CatchBreakpoint < Breakpoint
|
218
|
+
LABEL = generate_label("Catch")
|
219
|
+
attr_reader :last_exc
|
220
|
+
|
201
221
|
def initialize pat
|
202
222
|
@pat = pat.freeze
|
203
223
|
@key = [:catch, @pat].freeze
|
224
|
+
@last_exc = nil
|
204
225
|
|
205
226
|
super()
|
206
227
|
end
|
@@ -208,18 +229,30 @@ module DEBUGGER__
|
|
208
229
|
def setup
|
209
230
|
@tp = TracePoint.new(:raise){|tp|
|
210
231
|
exc = tp.raised_exception
|
232
|
+
should_suspend = false
|
211
233
|
exc.class.ancestors.each{|cls|
|
212
|
-
|
234
|
+
if @pat === cls.name
|
235
|
+
should_suspend = true
|
236
|
+
@last_exc = exc
|
237
|
+
break
|
238
|
+
end
|
213
239
|
}
|
240
|
+
suspend if should_suspend
|
214
241
|
}
|
215
242
|
end
|
216
243
|
|
217
244
|
def to_s
|
218
|
-
"
|
245
|
+
"#{LABEL} #{@pat.inspect}"
|
246
|
+
end
|
247
|
+
|
248
|
+
def description
|
249
|
+
"#{@last_exc.inspect} is raised."
|
219
250
|
end
|
220
251
|
end
|
221
252
|
|
222
253
|
class CheckBreakpoint < Breakpoint
|
254
|
+
LABEL = generate_label("Check")
|
255
|
+
|
223
256
|
def initialize expr
|
224
257
|
@expr = expr.freeze
|
225
258
|
@key = [:check, @expr].freeze
|
@@ -231,6 +264,8 @@ module DEBUGGER__
|
|
231
264
|
@tp = TracePoint.new(:line){|tp|
|
232
265
|
next if tp.path.start_with? __dir__
|
233
266
|
next if tp.path.start_with? '<internal:'
|
267
|
+
# Skip when `JSON.generate` is called during tests
|
268
|
+
next if tp.defined_class.to_s == '#<Class:JSON>' and ENV['RUBY_DEBUG_TEST_MODE']
|
234
269
|
|
235
270
|
if safe_eval tp.binding, @expr
|
236
271
|
suspend
|
@@ -239,21 +274,24 @@ module DEBUGGER__
|
|
239
274
|
end
|
240
275
|
|
241
276
|
def to_s
|
242
|
-
"
|
277
|
+
"#{LABEL} #{@expr}"
|
243
278
|
end
|
244
279
|
end
|
245
280
|
|
246
|
-
class
|
247
|
-
|
248
|
-
|
249
|
-
|
281
|
+
class WatchIVarBreakpoint < Breakpoint
|
282
|
+
LABEL = generate_label("Watch")
|
283
|
+
|
284
|
+
def initialize ivar, object, current
|
285
|
+
@ivar = ivar.to_sym
|
286
|
+
@object = object
|
287
|
+
@key = [:watch, @ivar].freeze
|
250
288
|
|
251
289
|
@current = current
|
252
290
|
super()
|
253
291
|
end
|
254
292
|
|
255
|
-
def watch_eval
|
256
|
-
result =
|
293
|
+
def watch_eval
|
294
|
+
result = @object.instance_variable_get(@ivar)
|
257
295
|
if result != @current
|
258
296
|
begin
|
259
297
|
@prev = @current
|
@@ -263,7 +301,7 @@ module DEBUGGER__
|
|
263
301
|
remove_instance_variable(:@prev)
|
264
302
|
end
|
265
303
|
end
|
266
|
-
rescue Exception
|
304
|
+
rescue Exception
|
267
305
|
false
|
268
306
|
end
|
269
307
|
|
@@ -272,20 +310,25 @@ module DEBUGGER__
|
|
272
310
|
next if tp.path.start_with? __dir__
|
273
311
|
next if tp.path.start_with? '<internal:'
|
274
312
|
|
275
|
-
watch_eval
|
313
|
+
watch_eval
|
276
314
|
}
|
277
315
|
end
|
278
316
|
|
279
317
|
def to_s
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
318
|
+
value_str =
|
319
|
+
if defined?(@prev)
|
320
|
+
"#{@prev} -> #{@current}"
|
321
|
+
else
|
322
|
+
"#{@current}"
|
323
|
+
end
|
324
|
+
"#{LABEL} #{@object} #{@ivar} = #{value_str}"
|
285
325
|
end
|
286
326
|
end
|
287
327
|
|
288
328
|
class MethodBreakpoint < Breakpoint
|
329
|
+
LABEL = generate_label("Method")
|
330
|
+
PENDING_LABEL = generate_label("Method (pending)")
|
331
|
+
|
289
332
|
attr_reader :sig_method_name, :method
|
290
333
|
|
291
334
|
def initialize b, klass_name, op, method_name, cond
|
@@ -345,18 +388,22 @@ module DEBUGGER__
|
|
345
388
|
retried = false
|
346
389
|
@tp.enable(target: @method)
|
347
390
|
|
348
|
-
rescue ArgumentError
|
391
|
+
rescue ArgumentError
|
349
392
|
raise if retried
|
350
393
|
retried = true
|
394
|
+
sig_method_name = @sig_method_name
|
351
395
|
|
352
396
|
# maybe C method
|
353
397
|
@klass.module_eval do
|
354
|
-
orig_name =
|
355
|
-
alias_method orig_name,
|
356
|
-
define_method(
|
398
|
+
orig_name = sig_method_name + '__orig__'
|
399
|
+
alias_method orig_name, sig_method_name
|
400
|
+
define_method(sig_method_name) do |*args|
|
357
401
|
send(orig_name, *args)
|
358
402
|
end
|
359
403
|
end
|
404
|
+
|
405
|
+
# re-collect the method object after the above patch
|
406
|
+
search_method
|
360
407
|
retry
|
361
408
|
end
|
362
409
|
rescue Exception
|
@@ -369,9 +416,9 @@ module DEBUGGER__
|
|
369
416
|
|
370
417
|
def to_s
|
371
418
|
if @method
|
372
|
-
"
|
419
|
+
"#{LABEL} #{sig}"
|
373
420
|
else
|
374
|
-
"
|
421
|
+
"#{PENDING_LABEL} #{sig}"
|
375
422
|
end + super
|
376
423
|
end
|
377
424
|
end
|