debug 1.0.0.rc1 → 1.2.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/README.md +26 -14
- data/Rakefile +1 -1
- data/TODO.md +4 -8
- data/exe/rdbg +1 -1
- data/ext/debug/debug.c +5 -0
- data/lib/debug/breakpoint.rb +14 -5
- data/lib/debug/color.rb +2 -2
- data/lib/debug/config.rb +18 -3
- data/lib/debug/console.rb +10 -2
- data/lib/debug/frame_info.rb +2 -2
- data/lib/debug/local.rb +21 -24
- data/lib/debug/server.rb +8 -7
- data/lib/debug/server_dap.rb +15 -6
- data/lib/debug/session.rb +258 -99
- data/lib/debug/thread_client.rb +23 -14
- data/lib/debug/tracer.rb +8 -3
- data/lib/debug/version.rb +1 -1
- data/misc/README.md.erb +18 -11
- metadata +4 -4
data/lib/debug/thread_client.rb
CHANGED
|
@@ -20,9 +20,11 @@ module DEBUGGER__
|
|
|
20
20
|
|
|
21
21
|
class ThreadClient
|
|
22
22
|
def self.current
|
|
23
|
-
Thread.current[:DEBUGGER__ThreadClient]
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
if thc = Thread.current[:DEBUGGER__ThreadClient]
|
|
24
|
+
thc
|
|
25
|
+
else
|
|
26
|
+
thc = SESSION.thread_client
|
|
27
|
+
Thread.current[:DEBUGGER__ThreadClient] = thc
|
|
26
28
|
end
|
|
27
29
|
end
|
|
28
30
|
|
|
@@ -115,7 +117,7 @@ module DEBUGGER__
|
|
|
115
117
|
# TODO: there is waiting -> waiting
|
|
116
118
|
# raise "#{mode} is given, but #{mode}" unless self.running?
|
|
117
119
|
else
|
|
118
|
-
raise
|
|
120
|
+
raise "unknown mode: #{mode}"
|
|
119
121
|
end
|
|
120
122
|
|
|
121
123
|
@mode = mode
|
|
@@ -138,7 +140,11 @@ module DEBUGGER__
|
|
|
138
140
|
end
|
|
139
141
|
|
|
140
142
|
def inspect
|
|
141
|
-
|
|
143
|
+
if bt = @thread.backtrace
|
|
144
|
+
"#<DBG:TC #{self.id}:#{@mode}@#{bt[-1]}>"
|
|
145
|
+
else # bt can be nil
|
|
146
|
+
"#<DBG:TC #{self.id}:#{@mode}>"
|
|
147
|
+
end
|
|
142
148
|
end
|
|
143
149
|
|
|
144
150
|
def to_s
|
|
@@ -194,10 +200,6 @@ module DEBUGGER__
|
|
|
194
200
|
wait_next_action
|
|
195
201
|
end
|
|
196
202
|
|
|
197
|
-
def on_thread_begin th
|
|
198
|
-
wait_reply [:thread_begin, th]
|
|
199
|
-
end
|
|
200
|
-
|
|
201
203
|
def on_load iseq, eval_src
|
|
202
204
|
wait_reply [:load, iseq, eval_src]
|
|
203
205
|
end
|
|
@@ -340,7 +342,8 @@ module DEBUGGER__
|
|
|
340
342
|
begin
|
|
341
343
|
@success_last_eval = false
|
|
342
344
|
|
|
343
|
-
b = current_frame
|
|
345
|
+
b = current_frame&.eval_binding || TOPLEVEL_BINDING
|
|
346
|
+
|
|
344
347
|
result = if b
|
|
345
348
|
f, _l = b.source_location
|
|
346
349
|
b.eval(src, "(rdbg)/#{f}")
|
|
@@ -356,7 +359,7 @@ module DEBUGGER__
|
|
|
356
359
|
|
|
357
360
|
puts "eval error: #{e}"
|
|
358
361
|
|
|
359
|
-
e.backtrace_locations
|
|
362
|
+
e.backtrace_locations&.each do |loc|
|
|
360
363
|
break if loc.path == __FILE__
|
|
361
364
|
puts " #{loc}"
|
|
362
365
|
end
|
|
@@ -659,18 +662,17 @@ module DEBUGGER__
|
|
|
659
662
|
|
|
660
663
|
def wait_next_action_
|
|
661
664
|
# assertions
|
|
662
|
-
raise "@mode is #{@mode}"
|
|
665
|
+
raise "@mode is #{@mode}" if !waiting?
|
|
663
666
|
|
|
664
667
|
unless SESSION.active?
|
|
665
668
|
pp caller
|
|
666
669
|
set_mode :running
|
|
667
670
|
return
|
|
668
671
|
end
|
|
669
|
-
# SESSION.check_forked
|
|
670
672
|
|
|
671
673
|
while true
|
|
672
674
|
begin
|
|
673
|
-
set_mode :waiting if
|
|
675
|
+
set_mode :waiting if !waiting?
|
|
674
676
|
cmds = @q_cmd.pop
|
|
675
677
|
# pp [self, cmds: cmds]
|
|
676
678
|
break unless cmds
|
|
@@ -779,6 +781,13 @@ module DEBUGGER__
|
|
|
779
781
|
end
|
|
780
782
|
when :call
|
|
781
783
|
result = frame_eval(eval_src)
|
|
784
|
+
when :irb
|
|
785
|
+
begin
|
|
786
|
+
result = frame_eval('binding.irb')
|
|
787
|
+
ensure
|
|
788
|
+
# workaround: https://github.com/ruby/debug/issues/308
|
|
789
|
+
Reline.prompt_proc = nil if defined? Reline
|
|
790
|
+
end
|
|
782
791
|
when :display, :try_display
|
|
783
792
|
failed_results = []
|
|
784
793
|
eval_src.each_with_index{|src, i|
|
data/lib/debug/tracer.rb
CHANGED
|
@@ -14,7 +14,7 @@ module DEBUGGER__
|
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
attr_reader :type
|
|
17
|
+
attr_reader :type, :key
|
|
18
18
|
|
|
19
19
|
def initialize ui, pattern: nil, into: nil
|
|
20
20
|
if /\ADEBUGGER__::(([A-Z][a-z]+?)[A-Z][a-z]+)/ =~ self.class.name
|
|
@@ -37,6 +37,8 @@ module DEBUGGER__
|
|
|
37
37
|
@output = ui
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
+
@key = [@type, @pattern, @into].freeze
|
|
41
|
+
|
|
40
42
|
enable
|
|
41
43
|
end
|
|
42
44
|
|
|
@@ -95,6 +97,8 @@ module DEBUGGER__
|
|
|
95
97
|
end
|
|
96
98
|
|
|
97
99
|
def minfo tp
|
|
100
|
+
return "block{}" if tp.event == :b_call
|
|
101
|
+
|
|
98
102
|
klass = tp.defined_class
|
|
99
103
|
|
|
100
104
|
if klass.singleton_class?
|
|
@@ -172,6 +176,7 @@ module DEBUGGER__
|
|
|
172
176
|
@obj_id = obj_id
|
|
173
177
|
@obj_inspect = obj_inspect
|
|
174
178
|
super(ui, **kw)
|
|
179
|
+
@key = [@type, @obj_id, @pattern, @into].freeze
|
|
175
180
|
end
|
|
176
181
|
|
|
177
182
|
def description
|
|
@@ -201,7 +206,7 @@ module DEBUGGER__
|
|
|
201
206
|
end
|
|
202
207
|
|
|
203
208
|
out tp, " #{colorized_obj_inspect} receives #{colorize_blue(method_info)}"
|
|
204
|
-
|
|
209
|
+
elsif !tp.parameters.empty?
|
|
205
210
|
b = tp.binding
|
|
206
211
|
method_info = colorize_blue(minfo(tp))
|
|
207
212
|
|
|
@@ -216,7 +221,7 @@ module DEBUGGER__
|
|
|
216
221
|
out tp, " #{colorized_obj_inspect} is used as a parameter #{colorized_name} of #{method_info}"
|
|
217
222
|
end
|
|
218
223
|
when :rest
|
|
219
|
-
next name == :"*"
|
|
224
|
+
next if name == :"*"
|
|
220
225
|
|
|
221
226
|
ary = b.local_variable_get(name)
|
|
222
227
|
ary.each{|e|
|
data/lib/debug/version.rb
CHANGED
data/misc/README.md.erb
CHANGED
|
@@ -8,7 +8,7 @@ This debug.rb is replacement of traditional lib/debug.rb standard library which
|
|
|
8
8
|
New debug.rb has several advantages:
|
|
9
9
|
|
|
10
10
|
* Fast: No performance penalty on non-stepping mode and non-breakpoints.
|
|
11
|
-
* Remote debugging: Support remote debugging natively.
|
|
11
|
+
* [Remote debugging](#remote-debugging): Support remote debugging natively.
|
|
12
12
|
* UNIX domain socket
|
|
13
13
|
* TCP/IP
|
|
14
14
|
* VSCode/DAP integration ([VSCode rdbg Ruby Debugger - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=KoichiSasada.vscode-rdbg))
|
|
@@ -25,7 +25,7 @@ New debug.rb has several advantages:
|
|
|
25
25
|
# Installation
|
|
26
26
|
|
|
27
27
|
```
|
|
28
|
-
$ gem install debug
|
|
28
|
+
$ gem install debug
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
or specify `-Ipath/to/debug/lib` in `RUBYOPT` or each ruby command-line option, especially for debug this gem development.
|
|
@@ -33,7 +33,7 @@ or specify `-Ipath/to/debug/lib` in `RUBYOPT` or each ruby command-line option,
|
|
|
33
33
|
If you use Bundler, write the following line to your Gemfile.
|
|
34
34
|
|
|
35
35
|
```
|
|
36
|
-
gem "debug", ">= 1.0.0
|
|
36
|
+
gem "debug", ">= 1.0.0"
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
# HOW TO USE
|
|
@@ -44,22 +44,24 @@ To use a debugger, roughly you will do the following steps:
|
|
|
44
44
|
2. Run a program with the debugger.
|
|
45
45
|
3. At the breakpoint, enter the debugger console.
|
|
46
46
|
4. Use debug commands.
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
47
|
+
* [Evaluate Ruby expressions](#evaluate) (e.g. `p lvar` to see the local variable `lvar`).
|
|
48
|
+
* [Query the program status](#information) (e.g. `info` to see information about the current frame).
|
|
49
|
+
* [Control program flow](#control-flow) (e.g. move to the another line with `step`, to the next line with `next`).
|
|
50
|
+
* [Set another breakpoint](#breakpoint) (e.g. `catch Exception` to set a breakpoint that'll be triggered when `Exception` is raised).
|
|
51
|
+
* [Activate tracing in your program](#trace) (e.g. `trace call` to trace method calls).
|
|
52
|
+
* [Change the configuration](#configuration-1) (e.g. `config set no_color true` to disable coloring).
|
|
51
53
|
* Continue the program (`c` or `continue`) and goto 3.
|
|
52
54
|
|
|
53
55
|
## Invoke with the debugger
|
|
54
56
|
|
|
55
57
|
There are several options for (1) and (2). Please choose your favorite way.
|
|
56
58
|
|
|
57
|
-
### Modify source code
|
|
59
|
+
### Modify source code with [`binding.break`](#bindingbreak-method) (similar to `binding.pry` or `binding.irb`)
|
|
58
60
|
|
|
59
|
-
If you can modify the source code, you can use the debugger by adding `require 'debug'` line at the top of your program and putting `binding.break` method (`binding.b` for short) into lines where you want to stop as breakpoints like `binding.pry` and `binding.irb`.
|
|
61
|
+
If you can modify the source code, you can use the debugger by adding `require 'debug'` line at the top of your program and putting [`binding.break`](#bindingbreak-method) method (`binding.b` for short) into lines where you want to stop as breakpoints like `binding.pry` and `binding.irb`.
|
|
60
62
|
After that, you run the program as usual and you will enter the debug console at breakpoints you inserted.
|
|
61
63
|
|
|
62
|
-
The following example shows the demonstration of `binding.break
|
|
64
|
+
The following example shows the demonstration of [`binding.break`](#bindingbreak-method).
|
|
63
65
|
|
|
64
66
|
```shell
|
|
65
67
|
$ cat target.rb # Sample program
|
|
@@ -370,7 +372,12 @@ If there are `~/.rdbgrc.rb` is available, it is also loaded as a ruby script at
|
|
|
370
372
|
|
|
371
373
|
On the debug console, you can use the following debug commands.
|
|
372
374
|
|
|
373
|
-
|
|
375
|
+
There are additional features:
|
|
376
|
+
|
|
377
|
+
* `<expr>` without debug command is almost same as `pp <expr>`.
|
|
378
|
+
* If the input line `<expr>` does *NOT* start with any debug command, the line `<expr>` will be evaluated as a Ruby expression and the result will be printed with `pp` method. So that the input `foo.bar` is same as `pp foo.bar`.
|
|
379
|
+
* If `<expr>` is recognized as a debug command, of course it is not evaluated as a Ruby expression, but is executed as debug command. For example, you can not evaluate such single letter local variables `i`, `b`, `n`, `c` because they are single letter debug commands. Use `p i` instead.
|
|
380
|
+
* `Enter` without any input repeats the last command (useful when repeating `step`s).
|
|
374
381
|
* `Ctrl-D` is equal to `quit` command.
|
|
375
382
|
* [debug command compare sheet - Google Sheets](https://docs.google.com/spreadsheets/d/1TlmmUDsvwK4sSIyoMv-io52BUUz__R5wpu-ComXlsw0/edit?usp=sharing)
|
|
376
383
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: debug
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
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-09-
|
|
11
|
+
date: 2021-09-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: irb
|
|
@@ -102,9 +102,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
102
102
|
version: 2.6.0
|
|
103
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
104
|
requirements:
|
|
105
|
-
- - "
|
|
105
|
+
- - ">="
|
|
106
106
|
- !ruby/object:Gem::Version
|
|
107
|
-
version:
|
|
107
|
+
version: '0'
|
|
108
108
|
requirements: []
|
|
109
109
|
rubygems_version: 3.1.6
|
|
110
110
|
signing_key:
|