debug 1.0.0.beta8 → 1.1.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/CONTRIBUTING.md +108 -106
- data/README.md +107 -40
- data/Rakefile +1 -1
- data/TODO.md +4 -8
- data/debug.gemspec +1 -0
- data/exe/rdbg +4 -7
- data/ext/debug/debug.c +11 -1
- data/lib/debug/breakpoint.rb +55 -22
- data/lib/debug/client.rb +7 -12
- data/lib/debug/color.rb +19 -4
- data/lib/debug/config.rb +362 -177
- data/lib/debug/console.rb +76 -68
- data/lib/debug/frame_info.rb +40 -7
- data/lib/debug/local.rb +91 -0
- data/lib/debug/server.rb +74 -26
- data/lib/debug/server_dap.rb +46 -12
- data/lib/debug/session.rb +637 -310
- data/lib/debug/thread_client.rb +620 -162
- data/lib/debug/tracer.rb +242 -0
- data/lib/debug/version.rb +1 -1
- data/misc/README.md.erb +41 -33
- metadata +20 -4
data/lib/debug/tracer.rb
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DEBUGGER__
|
|
4
|
+
class Tracer
|
|
5
|
+
include SkipPathHelper
|
|
6
|
+
include Color
|
|
7
|
+
|
|
8
|
+
def colorize(str, color)
|
|
9
|
+
# don't colorize trace sent into a file
|
|
10
|
+
if @into
|
|
11
|
+
str
|
|
12
|
+
else
|
|
13
|
+
super
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
attr_reader :type
|
|
18
|
+
|
|
19
|
+
def initialize ui, pattern: nil, into: nil
|
|
20
|
+
if /\ADEBUGGER__::(([A-Z][a-z]+?)[A-Z][a-z]+)/ =~ self.class.name
|
|
21
|
+
@name = $1
|
|
22
|
+
@type = $2.downcase
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
setup
|
|
26
|
+
|
|
27
|
+
if pattern
|
|
28
|
+
@pattern = Regexp.compile(pattern)
|
|
29
|
+
else
|
|
30
|
+
@pattern = nil
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
if @into = into
|
|
34
|
+
@output = File.open(into, 'w')
|
|
35
|
+
@output.puts "PID:#{Process.pid} #{self}"
|
|
36
|
+
else
|
|
37
|
+
@output = ui
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
enable
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def header depth
|
|
44
|
+
"DEBUGGER (trace/#{@type}) \#th:#{Thread.current.instance_variable_get(:@__thread_client_id)} \#depth:#{'%-2d'%depth}"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def enable
|
|
48
|
+
@tracer.enable
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def disable
|
|
52
|
+
@tracer.disable
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def description
|
|
56
|
+
nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def to_s
|
|
60
|
+
s = "#{@name}#{description} (#{@tracer.enabled? ? 'enabled' : 'disabled'})"
|
|
61
|
+
s += " with pattern #{@pattern.inspect}" if @pattern
|
|
62
|
+
s += " into: #{@into}" if @into
|
|
63
|
+
s
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def skip? tp
|
|
67
|
+
if tp.path.start_with?(__dir__) ||
|
|
68
|
+
tp.path.start_with?('<internal:') ||
|
|
69
|
+
ThreadClient.current.management? ||
|
|
70
|
+
skip_path?(tp.path) ||
|
|
71
|
+
skip_with_pattern?(tp)
|
|
72
|
+
true
|
|
73
|
+
else
|
|
74
|
+
false
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def skip_with_pattern?(tp)
|
|
79
|
+
@pattern && !tp.path.match?(@pattern)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def out tp, msg = nil, depth = caller.size - 1
|
|
83
|
+
location_str = colorize("#{tp.path}:#{tp.lineno}", [:GREEN])
|
|
84
|
+
buff = "#{header(depth)}#{msg} at #{location_str}"
|
|
85
|
+
|
|
86
|
+
if false # TODO: Ractor.main?
|
|
87
|
+
ThreadClient.current.on_trace self.object_id, buff
|
|
88
|
+
else
|
|
89
|
+
@output.puts buff
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def puts msg
|
|
94
|
+
@output.puts msg
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def minfo tp
|
|
98
|
+
klass = tp.defined_class
|
|
99
|
+
|
|
100
|
+
if klass.singleton_class?
|
|
101
|
+
"#{tp.self}.#{tp.method_id}"
|
|
102
|
+
else
|
|
103
|
+
"#{klass}\##{tp.method_id}"
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
class LineTracer < Tracer
|
|
109
|
+
def setup
|
|
110
|
+
@tracer = TracePoint.new(:line){|tp|
|
|
111
|
+
next if skip?(tp)
|
|
112
|
+
# pp tp.object_id, caller(0)
|
|
113
|
+
out tp
|
|
114
|
+
}
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
class CallTracer < Tracer
|
|
119
|
+
def setup
|
|
120
|
+
@tracer = TracePoint.new(:a_call, :a_return){|tp|
|
|
121
|
+
next if skip?(tp)
|
|
122
|
+
|
|
123
|
+
depth = caller.size
|
|
124
|
+
sp = ' ' * depth
|
|
125
|
+
|
|
126
|
+
call_identifier_str =
|
|
127
|
+
if tp.defined_class
|
|
128
|
+
minfo(tp)
|
|
129
|
+
else
|
|
130
|
+
"block"
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
call_identifier_str = colorize_blue(call_identifier_str)
|
|
134
|
+
|
|
135
|
+
case tp.event
|
|
136
|
+
when :call, :c_call, :b_call
|
|
137
|
+
depth += 1 if tp.event == :c_call
|
|
138
|
+
out tp, ">#{sp}#{call_identifier_str}", depth
|
|
139
|
+
when :return, :c_return, :b_return
|
|
140
|
+
depth += 1 if tp.event == :c_return
|
|
141
|
+
return_str = colorize_magenta(DEBUGGER__.short_inspect(tp.return_value))
|
|
142
|
+
out tp, "<#{sp}#{call_identifier_str} #=> #{return_str}", depth
|
|
143
|
+
end
|
|
144
|
+
}
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def skip_with_pattern?(tp)
|
|
148
|
+
super && !tp.method_id&.match?(@pattern)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
class ExceptionTracer < Tracer
|
|
153
|
+
def setup
|
|
154
|
+
@tracer = TracePoint.new(:raise) do |tp|
|
|
155
|
+
next if skip?(tp)
|
|
156
|
+
|
|
157
|
+
exc = tp.raised_exception
|
|
158
|
+
|
|
159
|
+
out tp, " #{colorize_magenta(exc.inspect)}"
|
|
160
|
+
rescue Exception => e
|
|
161
|
+
p e
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def skip_with_pattern?(tp)
|
|
166
|
+
super && !tp.raised_exception.inspect.match?(@pattern)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
class ObjectTracer < Tracer
|
|
171
|
+
def initialize ui, obj_id, obj_inspect, **kw
|
|
172
|
+
@obj_id = obj_id
|
|
173
|
+
@obj_inspect = obj_inspect
|
|
174
|
+
super(ui, **kw)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def description
|
|
178
|
+
" for #{@obj_inspect}"
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def colorized_obj_inspect
|
|
182
|
+
colorize_magenta(@obj_inspect)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def setup
|
|
186
|
+
@tracer = TracePoint.new(:a_call){|tp|
|
|
187
|
+
next if skip?(tp)
|
|
188
|
+
|
|
189
|
+
if tp.self.object_id == @obj_id
|
|
190
|
+
klass = tp.defined_class
|
|
191
|
+
method = tp.method_id
|
|
192
|
+
method_info =
|
|
193
|
+
if klass.singleton_class?
|
|
194
|
+
if tp.self.is_a?(Class)
|
|
195
|
+
".#{method} (#{klass}.#{method})"
|
|
196
|
+
else
|
|
197
|
+
".#{method}"
|
|
198
|
+
end
|
|
199
|
+
else
|
|
200
|
+
"##{method} (#{klass}##{method})"
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
out tp, " #{colorized_obj_inspect} receives #{colorize_blue(method_info)}"
|
|
204
|
+
else
|
|
205
|
+
b = tp.binding
|
|
206
|
+
method_info = colorize_blue(minfo(tp))
|
|
207
|
+
|
|
208
|
+
tp.parameters.each{|type, name|
|
|
209
|
+
next unless name
|
|
210
|
+
|
|
211
|
+
colorized_name = colorize_cyan(name)
|
|
212
|
+
|
|
213
|
+
case type
|
|
214
|
+
when :req, :opt, :key, :keyreq
|
|
215
|
+
if b.local_variable_get(name).object_id == @obj_id
|
|
216
|
+
out tp, " #{colorized_obj_inspect} is used as a parameter #{colorized_name} of #{method_info}"
|
|
217
|
+
end
|
|
218
|
+
when :rest
|
|
219
|
+
next if name == :"*"
|
|
220
|
+
|
|
221
|
+
ary = b.local_variable_get(name)
|
|
222
|
+
ary.each{|e|
|
|
223
|
+
if e.object_id == @obj_id
|
|
224
|
+
out tp, " #{colorized_obj_inspect} is used as a parameter in #{colorized_name} of #{method_info}"
|
|
225
|
+
end
|
|
226
|
+
}
|
|
227
|
+
when :keyrest
|
|
228
|
+
next if name == :'**'
|
|
229
|
+
h = b.local_variable_get(name)
|
|
230
|
+
h.each{|k, e|
|
|
231
|
+
if e.object_id == @obj_id
|
|
232
|
+
out tp, " #{colorized_obj_inspect} is used as a parameter in #{colorized_name} of #{method_info}"
|
|
233
|
+
end
|
|
234
|
+
}
|
|
235
|
+
end
|
|
236
|
+
}
|
|
237
|
+
end
|
|
238
|
+
}
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
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))
|
|
@@ -20,11 +20,12 @@ New debug.rb has several advantages:
|
|
|
20
20
|
* Support threads (almost done) and ractors (TODO).
|
|
21
21
|
* Support suspending and entering to the console debugging with `Ctrl-C` at most of timing.
|
|
22
22
|
* Show parameters on backtrace command.
|
|
23
|
+
* Support recording & reply debugging.
|
|
23
24
|
|
|
24
25
|
# Installation
|
|
25
26
|
|
|
26
27
|
```
|
|
27
|
-
$ gem install debug
|
|
28
|
+
$ gem install debug
|
|
28
29
|
```
|
|
29
30
|
|
|
30
31
|
or specify `-Ipath/to/debug/lib` in `RUBYOPT` or each ruby command-line option, especially for debug this gem development.
|
|
@@ -32,7 +33,7 @@ or specify `-Ipath/to/debug/lib` in `RUBYOPT` or each ruby command-line option,
|
|
|
32
33
|
If you use Bundler, write the following line to your Gemfile.
|
|
33
34
|
|
|
34
35
|
```
|
|
35
|
-
gem "debug", ">= 1.0.0
|
|
36
|
+
gem "debug", ">= 1.0.0"
|
|
36
37
|
```
|
|
37
38
|
|
|
38
39
|
# HOW TO USE
|
|
@@ -43,25 +44,27 @@ To use a debugger, roughly you will do the following steps:
|
|
|
43
44
|
2. Run a program with the debugger.
|
|
44
45
|
3. At the breakpoint, enter the debugger console.
|
|
45
46
|
4. Use debug commands.
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
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).
|
|
50
53
|
* Continue the program (`c` or `continue`) and goto 3.
|
|
51
54
|
|
|
52
55
|
## Invoke with the debugger
|
|
53
56
|
|
|
54
57
|
There are several options for (1) and (2). Please choose your favorite way.
|
|
55
58
|
|
|
56
|
-
### Modify source code
|
|
59
|
+
### Modify source code with [`binding.break`](#bindingbreak-method) (similar to `binding.pry` or `binding.irb`)
|
|
57
60
|
|
|
58
|
-
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`.
|
|
59
|
-
After that, you run the program as
|
|
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`.
|
|
62
|
+
After that, you run the program as usual and you will enter the debug console at breakpoints you inserted.
|
|
60
63
|
|
|
61
|
-
The following example shows the demonstration of `binding.break
|
|
64
|
+
The following example shows the demonstration of [`binding.break`](#bindingbreak-method).
|
|
62
65
|
|
|
63
66
|
```shell
|
|
64
|
-
$ cat target.rb # Sample
|
|
67
|
+
$ cat target.rb # Sample program
|
|
65
68
|
require 'debug'
|
|
66
69
|
|
|
67
70
|
a = 1
|
|
@@ -120,13 +123,13 @@ d => 4
|
|
|
120
123
|
[1, 2, 3, 4]
|
|
121
124
|
```
|
|
122
125
|
|
|
123
|
-
### Invoke the
|
|
126
|
+
### Invoke the program from the debugger as a traditional debuggers
|
|
124
127
|
|
|
125
128
|
If you don't want to modify the source code, you can set breakpoints with a debug command `break` (`b` for short).
|
|
126
129
|
Using `rdbg` command to launch the program without any modifications, you can run the program with the debugger.
|
|
127
130
|
|
|
128
131
|
```shell
|
|
129
|
-
$ cat target.rb # Sample
|
|
132
|
+
$ cat target.rb # Sample program
|
|
130
133
|
a = 1
|
|
131
134
|
b = 2
|
|
132
135
|
c = 3
|
|
@@ -241,16 +244,16 @@ NOTE: If you want to use bundler (`bundle` command), you need to write `gem debu
|
|
|
241
244
|
|
|
242
245
|
### Using VSCode
|
|
243
246
|
|
|
244
|
-
Like other
|
|
247
|
+
Like other languages, you can use this debugger on the VSCode.
|
|
245
248
|
|
|
246
|
-
1. Install [VSCode rdbg Ruby Debugger - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=KoichiSasada.vscode-rdbg)
|
|
249
|
+
1. Install [VSCode rdbg Ruby Debugger - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=KoichiSasada.vscode-rdbg)
|
|
247
250
|
2. Open `.rb` file (e.g. `target.rb`)
|
|
248
251
|
3. Register breakpoints with "Toggle breakpoint" in Run menu (or type F9 key)
|
|
249
252
|
4. Choose "Start debugging" in "Run" menu (or type F5 key)
|
|
250
253
|
5. You will see a dialog "Debug command line" and you can choose your favorite command line your want to run.
|
|
251
|
-
6.
|
|
254
|
+
6. Chosen command line is invoked with `rdbg -c` and VSCode shows the details at breakpoints.
|
|
252
255
|
|
|
253
|
-
|
|
256
|
+
Please refer [Debugging in Visual Studio Code](https://code.visualstudio.com/docs/editor/debugging) for operations on VSCode.
|
|
254
257
|
|
|
255
258
|
You can configure the extension in `.vscode/launch.json`.
|
|
256
259
|
Please see the extension page for more details.
|
|
@@ -265,7 +268,7 @@ You can use this debugger as a remote debugger. For example, it will help the fo
|
|
|
265
268
|
* Your application uses pipe for STDIN or STDOUT.
|
|
266
269
|
* Your application is running as a daemon and you want to query the running status (checking a backtrace and so on).
|
|
267
270
|
|
|
268
|
-
You can run your application as a remote debuggee and the remote debugger console can attach to the
|
|
271
|
+
You can run your application as a remote debuggee and the remote debugger console can attach to the debuggee anytime.
|
|
269
272
|
|
|
270
273
|
### Invoke as a remote debuggee
|
|
271
274
|
|
|
@@ -279,10 +282,10 @@ You can run a script with `rdbg --open target.rb` command and run a `target.rb`
|
|
|
279
282
|
$ exe/rdbg --open target.rb
|
|
280
283
|
DEBUGGER: Session start (pid: 7773)
|
|
281
284
|
DEBUGGER: Debugger can attach via UNIX domain socket (/home/ko1/.ruby-debug-sock/ruby-debug-ko1-7773)
|
|
282
|
-
DEBUGGER: wait for
|
|
285
|
+
DEBUGGER: wait for debugger connection...
|
|
283
286
|
```
|
|
284
287
|
|
|
285
|
-
By
|
|
288
|
+
By default, `rdbg --open` uses UNIX domain socket and generates path name automatically (`/home/ko1/.ruby-debug-sock/ruby-debug-ko1-7773` in this case).
|
|
286
289
|
|
|
287
290
|
You can connect to the debuggee with `rdbg --attach` command (`rdbg -A` for short).
|
|
288
291
|
|
|
@@ -309,7 +312,7 @@ NOTE: If you use `quit` command, only remote console exits and the debuggee prog
|
|
|
309
312
|
|
|
310
313
|
If you want to use TCP/IP for the remote debugging, you need to specify the port and host with `--port` like `rdbg --open --port 12345` and it binds to `localhost:12345`.
|
|
311
314
|
|
|
312
|
-
To connect to the
|
|
315
|
+
To connect to the debuggee, you need to specify the port.
|
|
313
316
|
|
|
314
317
|
```shell
|
|
315
318
|
$ rdbg --attach 12345
|
|
@@ -324,7 +327,7 @@ If you can modify the program, you can open debugging port by adding `require 'd
|
|
|
324
327
|
|
|
325
328
|
If you don't want to stop the program at the beginning, you can also use `require 'debug/open_nonstop'`.
|
|
326
329
|
Using `debug/open_nonstop` is useful if you want to open a backdoor to the application.
|
|
327
|
-
However, it is also danger because it can become
|
|
330
|
+
However, it is also danger because it can become another vulnerability.
|
|
328
331
|
Please use it carefully.
|
|
329
332
|
|
|
330
333
|
By default, UNIX domain socket is used for the debugging port. To use TCP/IP, you can set the `RUBY_DEBUG_PORT` environment variable.
|
|
@@ -336,14 +339,14 @@ $ RUBY_DEBUG_PORT=12345 ruby target.rb
|
|
|
336
339
|
## Configuration
|
|
337
340
|
|
|
338
341
|
You can configure the debugger's behavior with debug commands and environment variables.
|
|
339
|
-
When the debug session is started, initial scripts are loaded so you can put your favorite configurations in the
|
|
342
|
+
When the debug session is started, initial scripts are loaded so you can put your favorite configurations in the initial scripts.
|
|
340
343
|
|
|
341
344
|
### Configuration list
|
|
342
345
|
|
|
343
346
|
You can configure debugger's behavior with environment variables and `config` command. Each configuration has environment variable and the name which can be specified by `config` command.
|
|
344
347
|
|
|
345
348
|
```
|
|
346
|
-
#
|
|
349
|
+
# configuration example
|
|
347
350
|
config set log_level INFO
|
|
348
351
|
config set no_color true
|
|
349
352
|
```
|
|
@@ -355,7 +358,7 @@ config set no_color true
|
|
|
355
358
|
|
|
356
359
|
### Initial scripts
|
|
357
360
|
|
|
358
|
-
If there is `~/.rdbgrc`, the file is loaded as an initial
|
|
361
|
+
If there is `~/.rdbgrc`, the file is loaded as an initial script (which contains debug commands) when the debug session is started.
|
|
359
362
|
|
|
360
363
|
* `RUBY_DEBUG_INIT_SCRIPT` environment variable can specify the initial script file.
|
|
361
364
|
* You can specify the initial script with `rdbg -x initial_script` (like gdb's `-x` option).
|
|
@@ -369,7 +372,12 @@ If there are `~/.rdbgrc.rb` is available, it is also loaded as a ruby script at
|
|
|
369
372
|
|
|
370
373
|
On the debug console, you can use the following debug commands.
|
|
371
374
|
|
|
372
|
-
|
|
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).
|
|
373
381
|
* `Ctrl-D` is equal to `quit` command.
|
|
374
382
|
* [debug command compare sheet - Google Sheets](https://docs.google.com/spreadsheets/d/1TlmmUDsvwK4sSIyoMv-io52BUUz__R5wpu-ComXlsw0/edit?usp=sharing)
|
|
375
383
|
|
|
@@ -395,7 +403,7 @@ You can start debugging without `rdbg` command by requiring the following librar
|
|
|
395
403
|
You need to require one of them at the very beginning of the application.
|
|
396
404
|
Using `ruby -r` (for example `ruby -r debug/start target.rb`) is another way to invoke with debugger.
|
|
397
405
|
|
|
398
|
-
NOTE: Until Ruby 3.0, there is old `lib/debug.rb` standard library. So that if this gem is not installed, or if `Gemfile` missed to list this gem and `
|
|
406
|
+
NOTE: Until Ruby 3.0, there is old `lib/debug.rb` standard library. So that if this gem is not installed, or if `Gemfile` missed to list this gem and `bundle exec` is used, you will see the following output:
|
|
399
407
|
|
|
400
408
|
```shell
|
|
401
409
|
$ ruby -r debug -e0
|
|
@@ -411,7 +419,7 @@ Emacs support available.
|
|
|
411
419
|
|
|
412
420
|
#### Start by method
|
|
413
421
|
|
|
414
|
-
After loading `debug/session`, you can start debug session with the following methods. They are
|
|
422
|
+
After loading `debug/session`, you can start debug session with the following methods. They are convenient if you want to specify debug configurations in your program.
|
|
415
423
|
|
|
416
424
|
* `DEBUGGER__.start(**kw)`: start debug session with local console.
|
|
417
425
|
* `DEBUGGER__.open(**kw)`: open debug port with configuration (without configurations open with UNIX domain socket)
|
|
@@ -436,15 +444,15 @@ If `do: 'command'` is specified, the debugger suspends the program and run the `
|
|
|
436
444
|
It is useful if you only want to call a debug command and don't want to stop there.
|
|
437
445
|
|
|
438
446
|
```
|
|
439
|
-
def
|
|
447
|
+
def initialize
|
|
440
448
|
@a = 1
|
|
441
449
|
binding.b do: 'watch @a'
|
|
442
450
|
end
|
|
443
451
|
```
|
|
444
452
|
|
|
445
|
-
On this case, register a watch
|
|
453
|
+
On this case, register a watch breakpoint for `@a` and continue to run.
|
|
446
454
|
|
|
447
|
-
If `pre: 'command'` is specified, the
|
|
455
|
+
If `pre: 'command'` is specified, the debugger suspends the program and run the `command` as a debug command, and keep suspend.
|
|
448
456
|
It is useful if you have operations before suspend.
|
|
449
457
|
|
|
450
458
|
```
|
|
@@ -454,7 +462,7 @@ def foo
|
|
|
454
462
|
end
|
|
455
463
|
```
|
|
456
464
|
|
|
457
|
-
On this case, you can see the result of `bar()`
|
|
465
|
+
On this case, you can see the result of `bar()` every time you stop there.
|
|
458
466
|
|
|
459
467
|
## rdbg command help
|
|
460
468
|
|