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
File without changes
|
data/lib/debug/thread_client.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'objspace'
|
2
2
|
require 'pp'
|
3
|
-
|
3
|
+
|
4
4
|
require_relative 'frame_info'
|
5
|
+
require_relative 'color'
|
5
6
|
|
6
7
|
module DEBUGGER__
|
7
8
|
class ThreadClient
|
@@ -12,23 +13,46 @@ module DEBUGGER__
|
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
16
|
+
include Color
|
17
|
+
|
15
18
|
attr_reader :location, :thread, :mode, :id
|
16
19
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
str
|
22
|
-
end
|
20
|
+
def assemble_arguments(args)
|
21
|
+
args.map do |arg|
|
22
|
+
"#{colorize_cyan(arg[:name])}=#{arg[:value]}"
|
23
|
+
end.join(", ")
|
23
24
|
end
|
24
25
|
|
25
26
|
def default_frame_formatter frame
|
26
|
-
call_identifier_str =
|
27
|
-
|
27
|
+
call_identifier_str =
|
28
|
+
case frame.frame_type
|
29
|
+
when :block
|
30
|
+
level, block_loc, args = frame.block_identifier
|
31
|
+
|
32
|
+
if !args.empty?
|
33
|
+
args_str = " {|#{assemble_arguments(args)}|}"
|
34
|
+
end
|
35
|
+
|
36
|
+
"#{colorize_blue("block")}#{args_str} in #{colorize_blue(block_loc + level)}"
|
37
|
+
when :method
|
38
|
+
ci, args = frame.method_identifier
|
39
|
+
|
40
|
+
if !args.empty?
|
41
|
+
args_str = "(#{assemble_arguments(args)})"
|
42
|
+
end
|
43
|
+
|
44
|
+
"#{colorize_blue(ci)}#{args_str}"
|
45
|
+
when :c
|
46
|
+
colorize_blue(frame.c_identifier)
|
47
|
+
when :other
|
48
|
+
colorize_blue(frame.other_identifier)
|
49
|
+
end
|
50
|
+
|
51
|
+
location_str = colorize(frame.location_str, [:GREEN])
|
28
52
|
result = "#{call_identifier_str} at #{location_str}"
|
29
53
|
|
30
54
|
if return_str = frame.return_str
|
31
|
-
return_str = colorize(frame.return_str, [:MAGENTA])
|
55
|
+
return_str = colorize(frame.return_str, [:MAGENTA, :BOLD])
|
32
56
|
result += " #=> #{return_str}"
|
33
57
|
end
|
34
58
|
|
@@ -38,6 +62,7 @@ module DEBUGGER__
|
|
38
62
|
def initialize id, q_evt, q_cmd, thr = Thread.current
|
39
63
|
@id = id
|
40
64
|
@thread = thr
|
65
|
+
@target_frames = nil
|
41
66
|
@q_evt = q_evt
|
42
67
|
@q_cmd = q_cmd
|
43
68
|
@step_tp = nil
|
@@ -45,9 +70,14 @@ module DEBUGGER__
|
|
45
70
|
@src_lines_on_stop = (::DEBUGGER__::CONFIG[:show_src_lines] || 10).to_i
|
46
71
|
@show_frames_on_stop = (::DEBUGGER__::CONFIG[:show_frames] || 2).to_i
|
47
72
|
@frame_formatter = method(:default_frame_formatter)
|
73
|
+
@var_map = {} # { thread_local_var_id => obj } for DAP
|
48
74
|
set_mode nil
|
49
75
|
end
|
50
76
|
|
77
|
+
def name
|
78
|
+
"##{@id} #{@thread.name || @thread.backtrace.last}"
|
79
|
+
end
|
80
|
+
|
51
81
|
def close
|
52
82
|
@q_cmd.close
|
53
83
|
end
|
@@ -71,8 +101,14 @@ module DEBUGGER__
|
|
71
101
|
@q_cmd << req
|
72
102
|
end
|
73
103
|
|
104
|
+
def generate_info
|
105
|
+
return unless current_frame
|
106
|
+
|
107
|
+
{ location: current_frame.location_str, line: current_frame.location.lineno }
|
108
|
+
end
|
109
|
+
|
74
110
|
def event! ev, *args
|
75
|
-
@q_evt << [self, @output, ev, *args]
|
111
|
+
@q_evt << [self, @output, ev, generate_info, *args]
|
76
112
|
@output = []
|
77
113
|
end
|
78
114
|
|
@@ -116,6 +152,11 @@ module DEBUGGER__
|
|
116
152
|
cf.has_return_value = true
|
117
153
|
cf.return_value = tp.return_value
|
118
154
|
end
|
155
|
+
|
156
|
+
if CatchBreakpoint === bp
|
157
|
+
cf.has_raised_exception = true
|
158
|
+
cf.raised_exception = bp.last_exc
|
159
|
+
end
|
119
160
|
end
|
120
161
|
|
121
162
|
if event != :pause
|
@@ -187,7 +228,6 @@ module DEBUGGER__
|
|
187
228
|
start_line: nil,
|
188
229
|
end_line: nil,
|
189
230
|
dir: +1)
|
190
|
-
|
191
231
|
if @target_frames && frame = @target_frames[frame_index]
|
192
232
|
if file_lines = frame.file_lines
|
193
233
|
frame_line = frame.location.lineno - 1
|
@@ -229,6 +269,10 @@ module DEBUGGER__
|
|
229
269
|
puts "# No sourcefile available for #{frame.path}"
|
230
270
|
end
|
231
271
|
end
|
272
|
+
rescue Exception => e
|
273
|
+
p e
|
274
|
+
pp e.backtrace
|
275
|
+
exit!
|
232
276
|
end
|
233
277
|
|
234
278
|
def show_by_editor path = nil
|
@@ -255,14 +299,18 @@ module DEBUGGER__
|
|
255
299
|
|
256
300
|
def show_locals
|
257
301
|
if s = current_frame&.self
|
258
|
-
puts " %self => #{s}"
|
302
|
+
puts " #{colorize_cyan("%self")} => #{colored_inspect(s)}"
|
259
303
|
end
|
260
304
|
if current_frame&.has_return_value
|
261
|
-
puts " %return => #{current_frame.return_value}"
|
305
|
+
puts " #{colorize_cyan("%return")} => #{colored_inspect(current_frame.return_value)}"
|
306
|
+
end
|
307
|
+
if current_frame&.has_raised_exception
|
308
|
+
puts " #{colorize_cyan("%raised")} => #{colored_inspect(current_frame.raised_exception)}"
|
262
309
|
end
|
263
310
|
if b = current_frame&.binding
|
264
311
|
b.local_variables.each{|loc|
|
265
|
-
|
312
|
+
value = b.local_variable_get(loc)
|
313
|
+
puts " #{colorize_cyan(loc)} => #{colored_inspect(value)}"
|
266
314
|
}
|
267
315
|
end
|
268
316
|
end
|
@@ -270,7 +318,8 @@ module DEBUGGER__
|
|
270
318
|
def show_ivars
|
271
319
|
if s = current_frame&.self
|
272
320
|
s.instance_variables.each{|iv|
|
273
|
-
|
321
|
+
value = s.instance_variable_get(iv)
|
322
|
+
puts " #{colorize_cyan(iv)} => #{colored_inspect(value)}"
|
274
323
|
}
|
275
324
|
end
|
276
325
|
end
|
@@ -281,7 +330,7 @@ module DEBUGGER__
|
|
281
330
|
|
282
331
|
b = current_frame.binding
|
283
332
|
result = if b
|
284
|
-
f,
|
333
|
+
f, _l = b.source_location
|
285
334
|
b.eval(src, "(rdbg)/#{f}")
|
286
335
|
else
|
287
336
|
frame_self = current_frame.self
|
@@ -312,7 +361,7 @@ module DEBUGGER__
|
|
312
361
|
end
|
313
362
|
|
314
363
|
def show_frames max = (@target_frames || []).size
|
315
|
-
if max > 0 &&
|
364
|
+
if max > 0 && @target_frames
|
316
365
|
size = @target_frames.size
|
317
366
|
max += 1 if size == max + 1
|
318
367
|
max.times{|i|
|
@@ -369,6 +418,8 @@ module DEBUGGER__
|
|
369
418
|
def wait_next_action
|
370
419
|
set_mode :wait_next_action
|
371
420
|
|
421
|
+
SESSION.check_forked
|
422
|
+
|
372
423
|
while cmds = @q_cmd.pop
|
373
424
|
# pp [self, cmds: cmds]
|
374
425
|
|
@@ -397,9 +448,13 @@ module DEBUGGER__
|
|
397
448
|
loc = caller_locations(2, 1).first
|
398
449
|
loc_path = loc.absolute_path || "!eval:#{loc.path}"
|
399
450
|
|
451
|
+
# same stack depth
|
452
|
+
(DEBUGGER__.frame_depth - 3 <= depth) ||
|
453
|
+
|
454
|
+
# different frame
|
400
455
|
(next_line && loc_path == path &&
|
401
|
-
|
402
|
-
|
456
|
+
(loc_lineno = loc.lineno) > line &&
|
457
|
+
loc_lineno <= next_line)
|
403
458
|
}
|
404
459
|
when :finish
|
405
460
|
depth = @target_frames.first.frame_depth
|
@@ -426,7 +481,7 @@ module DEBUGGER__
|
|
426
481
|
puts "=> " + result.inspect
|
427
482
|
when :pp
|
428
483
|
puts "=> "
|
429
|
-
PP.pp(result, out = ''.dup)
|
484
|
+
PP.pp(result, out = ''.dup, SESSION.width)
|
430
485
|
puts out
|
431
486
|
when :call
|
432
487
|
result = frame_eval(eval_src)
|
@@ -444,8 +499,17 @@ module DEBUGGER__
|
|
444
499
|
result = failed_results
|
445
500
|
when :watch
|
446
501
|
if @success_last_eval
|
447
|
-
|
448
|
-
|
502
|
+
if eval_src.match?(/@\w+/)
|
503
|
+
object =
|
504
|
+
if b = current_frame.binding
|
505
|
+
b.receiver
|
506
|
+
else
|
507
|
+
current_frame.self
|
508
|
+
end
|
509
|
+
puts "#{object} #{eval_src} = #{result}"
|
510
|
+
result = WatchIVarBreakpoint.new(eval_src, object, result)
|
511
|
+
end
|
512
|
+
|
449
513
|
result_type = :watch
|
450
514
|
else
|
451
515
|
result = nil
|
@@ -515,6 +579,10 @@ module DEBUGGER__
|
|
515
579
|
|
516
580
|
when :breakpoint
|
517
581
|
add_breakpoint args
|
582
|
+
|
583
|
+
when :dap
|
584
|
+
process_dap args
|
585
|
+
|
518
586
|
else
|
519
587
|
raise [cmd, *args].inspect
|
520
588
|
end
|
data/lib/debug/version.rb
CHANGED
data/misc/README.md.erb
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
|
+
```
|
167
|
+
|
168
|
+
#### (3) Write `require 'debug/open'` in .rb files
|
158
169
|
|
159
|
-
|
160
|
-
|
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
|
+
```
|
270
|
+
|
271
|
+
and run with environment variable RUBY_DEBUG_PORT
|
255
272
|
|
256
|
-
|
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.
|
@@ -325,3 +344,7 @@ The `<...>` notation means the argument.
|
|
325
344
|
Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/debug.
|
326
345
|
|
327
346
|
Please also check the [contributing guideline](/CONTRIBUTING.md).
|
347
|
+
|
348
|
+
# Acknowledgement
|
349
|
+
|
350
|
+
* Some tests are based on [deivid-rodriguez/byebug: Debugging in Ruby 2](https://github.com/deivid-rodriguez/byebug)
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: debug
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.beta5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Koichi Sasada
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
12
|
-
dependencies:
|
11
|
+
date: 2021-06-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: irb
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
description: Debugging functionality for Ruby. This is completely rewritten debug.rb
|
14
28
|
which was contained by the encient Ruby versions.
|
15
29
|
email:
|
@@ -20,6 +34,7 @@ extensions:
|
|
20
34
|
- ext/debug/extconf.rb
|
21
35
|
extra_rdoc_files: []
|
22
36
|
files:
|
37
|
+
- ".github/workflows/ruby.yml"
|
23
38
|
- ".gitignore"
|
24
39
|
- CONTRIBUTING.md
|
25
40
|
- Gemfile
|
@@ -38,14 +53,17 @@ files:
|
|
38
53
|
- lib/debug/bp.vim
|
39
54
|
- lib/debug/breakpoint.rb
|
40
55
|
- lib/debug/client.rb
|
56
|
+
- lib/debug/color.rb
|
41
57
|
- lib/debug/config.rb
|
42
58
|
- lib/debug/console.rb
|
43
59
|
- lib/debug/frame_info.rb
|
44
60
|
- lib/debug/open.rb
|
45
61
|
- lib/debug/run.rb
|
46
62
|
- lib/debug/server.rb
|
63
|
+
- lib/debug/server_dap.rb
|
47
64
|
- lib/debug/session.rb
|
48
65
|
- lib/debug/source_repository.rb
|
66
|
+
- lib/debug/test_console.rb
|
49
67
|
- lib/debug/thread_client.rb
|
50
68
|
- lib/debug/version.rb
|
51
69
|
- misc/README.md.erb
|