debug 1.0.0.beta4 → 1.0.0.beta5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![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)
|
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
|