debug 1.0.0.beta5 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +213 -20
- data/Gemfile +1 -0
- data/README.md +460 -226
- data/Rakefile +2 -1
- data/TODO.md +0 -6
- data/bin/gentest +22 -0
- data/debug.gemspec +1 -0
- data/exe/rdbg +11 -18
- data/ext/debug/debug.c +11 -1
- data/lib/debug/breakpoint.rb +106 -62
- data/lib/debug/client.rb +11 -17
- data/lib/debug/color.rb +28 -7
- data/lib/debug/config.rb +378 -144
- data/lib/debug/console.rb +79 -57
- data/lib/debug/frame_info.rb +42 -8
- data/lib/debug/local.rb +91 -0
- data/lib/debug/open.rb +2 -1
- data/lib/debug/open_nonstop.rb +15 -0
- data/lib/debug/server.rb +96 -43
- data/lib/debug/server_dap.rb +34 -7
- data/lib/debug/session.rb +827 -341
- data/lib/debug/source_repository.rb +2 -0
- data/lib/debug/start.rb +5 -0
- data/lib/debug/thread_client.rb +691 -184
- data/lib/debug/tracer.rb +242 -0
- data/lib/debug/version.rb +3 -1
- data/lib/debug.rb +3 -0
- data/misc/README.md.erb +341 -216
- metadata +21 -4
- data/lib/debug/run.rb +0 -4
- data/lib/debug/test_console.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4753f123beef802e8cea541c779672938b200d5077011cd53a6a99c282d225cb
|
4
|
+
data.tar.gz: '078b495c6c5170cf6704c3100e1769477efadcbca47b5bae54c18c76424b8466'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e3e35a50f48444a978499798ef4d0ff997060f8562118baadec7af7c55ce4932f0a7ebd937dca974338c4086e44fbe34ce85b12386d3b67f65c774ab642a0b1
|
7
|
+
data.tar.gz: 3ba0fa3adf1122d4c86ac491c99a782d3f31d519255f4110e9721f3749bd87ac0aed2f9d1528a14b4ca814a3eb60ed0ef2f30cb51b24f6ec219e8b9ead6c5b73
|
data/CONTRIBUTING.md
CHANGED
@@ -15,8 +15,6 @@ If you spot any problem, please open an issue.
|
|
15
15
|
|
16
16
|
```bash
|
17
17
|
$ rake test
|
18
|
-
# or
|
19
|
-
$ ruby bin/test-unit.rb
|
20
18
|
```
|
21
19
|
|
22
20
|
### Run specific test(s)
|
@@ -27,6 +25,199 @@ $ ruby test/debug/bp_test.rb # run all tests in the specified file
|
|
27
25
|
$ ruby test/debug/bp_test.rb -h # to see all the test options
|
28
26
|
```
|
29
27
|
|
28
|
+
## Generate Tests
|
29
|
+
There is a test generator in `debug.rb` project to make it easier to write tests.
|
30
|
+
### Quickstart
|
31
|
+
This section shows you how to create test file by test generator. For more advanced informations on creating tests, please take a look at [gentest options](#gentest-options). (You can also check by `$bin/gentest -h`)
|
32
|
+
#### 1. Create a target file for debuggee.
|
33
|
+
Let's say, we created `target.rb` which is located in top level directory of debugger.
|
34
|
+
```ruby
|
35
|
+
module Foo
|
36
|
+
class Bar
|
37
|
+
def self.a
|
38
|
+
"hello"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
Bar.a
|
42
|
+
bar = Bar.new
|
43
|
+
end
|
44
|
+
```
|
45
|
+
#### 2. Run `gentest` as shown in the example below.
|
46
|
+
```shell
|
47
|
+
$ bin/gentest target.rb
|
48
|
+
```
|
49
|
+
#### 3. Debugger will be executed. You can type any debug commands.
|
50
|
+
```shell
|
51
|
+
$ bin/gentest target.rb
|
52
|
+
DEBUGGER: Session start (pid: 11139)
|
53
|
+
[1, 9] in ~/workspace/debug/target.rb
|
54
|
+
=> 1| module Foo
|
55
|
+
2| class Bar
|
56
|
+
3| def self.a
|
57
|
+
4| "hello"
|
58
|
+
5| end
|
59
|
+
6| end
|
60
|
+
7| Bar.a
|
61
|
+
8| bar = Bar.new
|
62
|
+
9| end
|
63
|
+
=>#0 <main> at ~/workspace/debug/target.rb:1
|
64
|
+
INTERNAL_INFO: {"location":"~/workspace/debug/target.rb:1","line":1}
|
65
|
+
(rdbg)s
|
66
|
+
s
|
67
|
+
[1, 9] in ~/workspace/debug/target.rb
|
68
|
+
1| module Foo
|
69
|
+
=> 2| class Bar
|
70
|
+
3| def self.a
|
71
|
+
4| "hello"
|
72
|
+
5| end
|
73
|
+
6| end
|
74
|
+
7| Bar.a
|
75
|
+
8| bar = Bar.new
|
76
|
+
9| end
|
77
|
+
=>#0 <module:Foo> at ~/workspace/debug/target.rb:2
|
78
|
+
#1 <main> at ~/workspace/debug/target.rb:1
|
79
|
+
INTERNAL_INFO: {"location":"~/workspace/debug/target.rb:2","line":2}
|
80
|
+
(rdbg)n
|
81
|
+
n
|
82
|
+
[1, 9] in ~/workspace/debug/target.rb
|
83
|
+
1| module Foo
|
84
|
+
2| class Bar
|
85
|
+
=> 3| def self.a
|
86
|
+
4| "hello"
|
87
|
+
5| end
|
88
|
+
6| end
|
89
|
+
7| Bar.a
|
90
|
+
8| bar = Bar.new
|
91
|
+
9| end
|
92
|
+
=>#0 <class:Bar> at ~/workspace/debug/target.rb:3
|
93
|
+
#1 <module:Foo> at ~/workspace/debug/target.rb:2
|
94
|
+
# and 1 frames (use `bt' command for all frames)
|
95
|
+
INTERNAL_INFO: {"location":"~/workspace/debug/target.rb:3","line":3}
|
96
|
+
(rdbg)b 7
|
97
|
+
b 7
|
98
|
+
#0 BP - Line /Users/naotto/workspace/debug/target.rb:7 (line)
|
99
|
+
INTERNAL_INFO: {"location":"~/workspace/debug/target.rb:3","line":3}
|
100
|
+
(rdbg)c
|
101
|
+
c
|
102
|
+
[2, 9] in ~/workspace/debug/target.rb
|
103
|
+
2| class Bar
|
104
|
+
3| def self.a
|
105
|
+
4| "hello"
|
106
|
+
5| end
|
107
|
+
6| end
|
108
|
+
=> 7| Bar.a
|
109
|
+
8| bar = Bar.new
|
110
|
+
9| end
|
111
|
+
=>#0 <module:Foo> at ~/workspace/debug/target.rb:7
|
112
|
+
#1 <main> at ~/workspace/debug/target.rb:1
|
113
|
+
|
114
|
+
Stop by #0 BP - Line /Users/naotto/workspace/debug/target.rb:7 (line)
|
115
|
+
INTERNAL_INFO: {"location":"~/workspace/debug/target.rb:7","line":7}
|
116
|
+
(rdbg)q!
|
117
|
+
q!
|
118
|
+
created: /Users/naotto/workspace/debug/test/tool/../debug/foo_test.rb
|
119
|
+
class: FooTest
|
120
|
+
method: test_1629720194
|
121
|
+
```
|
122
|
+
#### 4. The test file will be created as `test/debug/foo_test.rb`.
|
123
|
+
If the file already exists, **only method** will be added to it.
|
124
|
+
```ruby
|
125
|
+
# frozen_string_literal: true
|
126
|
+
|
127
|
+
require_relative '../support/test_case'
|
128
|
+
|
129
|
+
module DEBUGGER__
|
130
|
+
class FooTest < TestCase
|
131
|
+
def program
|
132
|
+
<<~RUBY
|
133
|
+
1| module Foo
|
134
|
+
2| class Bar
|
135
|
+
3| def self.a
|
136
|
+
4| "hello"
|
137
|
+
5| end
|
138
|
+
6| end
|
139
|
+
7| Bar.a
|
140
|
+
8| bar = Bar.new
|
141
|
+
9| end
|
142
|
+
RUBY
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_1629720194
|
146
|
+
debug_code(program) do
|
147
|
+
type 's'
|
148
|
+
assert_line_num 2
|
149
|
+
assert_line_text([
|
150
|
+
/\[1, 9\] in .*/,
|
151
|
+
/ 1\| module Foo/,
|
152
|
+
/=> 2\| class Bar/,
|
153
|
+
/ 3\| def self\.a/,
|
154
|
+
/ 4\| "hello"/,
|
155
|
+
/ 5\| end/,
|
156
|
+
/ 6\| end/,
|
157
|
+
/ 7\| Bar\.a/,
|
158
|
+
/ 8\| bar = Bar\.new/,
|
159
|
+
/ 9\| end/,
|
160
|
+
/=>\#0\t<module:Foo> at .*/,
|
161
|
+
/ \#1\t<main> at .*/
|
162
|
+
])
|
163
|
+
type 'n'
|
164
|
+
assert_line_num 3
|
165
|
+
assert_line_text([
|
166
|
+
/\[1, 9\] in .*/,
|
167
|
+
/ 1\| module Foo/,
|
168
|
+
/ 2\| class Bar/,
|
169
|
+
/=> 3\| def self\.a/,
|
170
|
+
/ 4\| "hello"/,
|
171
|
+
/ 5\| end/,
|
172
|
+
/ 6\| end/,
|
173
|
+
/ 7\| Bar\.a/,
|
174
|
+
/ 8\| bar = Bar\.new/,
|
175
|
+
/ 9\| end/,
|
176
|
+
/=>\#0\t<class:Bar> at .*/,
|
177
|
+
/ \#1\t<module:Foo> at .*/,
|
178
|
+
/ \# and 1 frames \(use `bt' command for all frames\)/
|
179
|
+
])
|
180
|
+
type 'b 7'
|
181
|
+
assert_line_text(/\#0 BP \- Line .*/)
|
182
|
+
type 'c'
|
183
|
+
assert_line_num 7
|
184
|
+
assert_line_text([
|
185
|
+
/\[2, 9\] in .*/,
|
186
|
+
/ 2\| class Bar/,
|
187
|
+
/ 3\| def self\.a/,
|
188
|
+
/ 4\| "hello"/,
|
189
|
+
/ 5\| end/,
|
190
|
+
/ 6\| end/,
|
191
|
+
/=> 7\| Bar\.a/,
|
192
|
+
/ 8\| bar = Bar\.new/,
|
193
|
+
/ 9\| end/,
|
194
|
+
/=>\#0\t<module:Foo> at .*/,
|
195
|
+
/ \#1\t<main> at .*/,
|
196
|
+
//,
|
197
|
+
/Stop by \#0 BP \- Line .*/
|
198
|
+
])
|
199
|
+
type 'q!'
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
```
|
205
|
+
|
206
|
+
#### gentest options
|
207
|
+
You can get more information about `gentest` here.
|
208
|
+
|
209
|
+
The default method name is `test_foo` and the class name is `FooTest`. The file name will be `[Lowercase letters with "Test" removed from the class name]_test.rb`.
|
210
|
+
```shell
|
211
|
+
# run without any options(test method name will be `test_foo`, class name will be `FooTest`, file name will be `foo_test.rb`)
|
212
|
+
$ bin/gentest target.rb
|
213
|
+
# specify the class name(test method name will be `test_foo`, class name will be `StepTest`, file name will be `step_test.rb`)
|
214
|
+
$ bin/gentest target.rb -c StepTest
|
215
|
+
# specify the method name(test method name will be `test_step`, class name will be `FooTest`, file name will be `foo_test.rb`)
|
216
|
+
$ bin/gentest target.rb -m test_step
|
217
|
+
# specify class name and method name(test method name will be `test_step`, class name will be `StepTest`, file name will be `step_test.rb`.)
|
218
|
+
$ bin/gentest target.rb -c StepTest -m test_step
|
219
|
+
```
|
220
|
+
|
30
221
|
## To Update README
|
31
222
|
|
32
223
|
This project generates `README.md` from the template `misc/README.md.erb`
|
@@ -96,6 +287,7 @@ $ exe/rdbg -e 'b 20;; c ;; bt ;; info ;; q!' -e c target.rb
|
|
96
287
|
|
97
288
|
```
|
98
289
|
❯ exe/rdbg -e 'b 20;; c ;; bt ;; info ;; q!' -e c target.rb
|
290
|
+
DEBUGGER: Session start (pid: 9815)
|
99
291
|
[1, 10] in target.rb
|
100
292
|
=> 1| class Foo
|
101
293
|
2| def first_call
|
@@ -108,10 +300,10 @@ $ exe/rdbg -e 'b 20;; c ;; bt ;; info ;; q!' -e c target.rb
|
|
108
300
|
9| end
|
109
301
|
10| end
|
110
302
|
=>#0 <main> at target.rb:1
|
111
|
-
(rdbg:
|
112
|
-
#
|
113
|
-
(rdbg:
|
114
|
-
[15,
|
303
|
+
(rdbg:commands) b 20
|
304
|
+
#0 BP - Line /PATH_TO_PROJECT/target.rb:20 (return)
|
305
|
+
(rdbg:commands) c
|
306
|
+
[15, 24] in target.rb
|
115
307
|
15| yield(10)
|
116
308
|
16| end
|
117
309
|
17|
|
@@ -121,25 +313,26 @@ $ exe/rdbg -e 'b 20;; c ;; bt ;; info ;; q!' -e c target.rb
|
|
121
313
|
21| end
|
122
314
|
22|
|
123
315
|
23| Foo.new.first_call
|
316
|
+
24|
|
124
317
|
=>#0 Foo#forth_call(num1=20, num2=10) at target.rb:20 #=> 30
|
125
|
-
#1 block{|ten=10|} in second_call at target.rb:8
|
318
|
+
#1 block {|ten=10|} in second_call at target.rb:8
|
126
319
|
# and 4 frames (use `bt' command for all frames)
|
127
320
|
|
128
|
-
Stop by #
|
129
|
-
(rdbg:
|
321
|
+
Stop by #0 BP - Line /PATH_TO_PROJECT/target.rb:20 (return)
|
322
|
+
(rdbg:commands) bt
|
130
323
|
=>#0 Foo#forth_call(num1=20, num2=10) at target.rb:20 #=> 30
|
131
|
-
#1 block{|ten=10|} in second_call at target.rb:8
|
132
|
-
#2 Foo#third_call_with_block(block=#<Proc:
|
324
|
+
#1 block {|ten=10|} in second_call at target.rb:8
|
325
|
+
#2 Foo#third_call_with_block(block=#<Proc:0x00007f9283101568 target.rb:7>) at target.rb:15
|
133
326
|
#3 Foo#second_call(num=20) at target.rb:7
|
134
|
-
#4 first_call at target.rb:3
|
327
|
+
#4 Foo#first_call at target.rb:3
|
135
328
|
#5 <main> at target.rb:23
|
136
|
-
(rdbg:
|
329
|
+
(rdbg:commands) info
|
137
330
|
=>#0 Foo#forth_call(num1=20, num2=10) at target.rb:20 #=> 30
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
(rdbg:
|
331
|
+
%self => #<Foo:0x00007f92831016d0 @ivar1=10, @ivar2=20>
|
332
|
+
%return => 30
|
333
|
+
num1 => 20
|
334
|
+
num2 => 10
|
335
|
+
@ivar1 => 10
|
336
|
+
@ivar2 => 20
|
337
|
+
(rdbg:commands) q!
|
145
338
|
```
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -11,8 +11,8 @@ New debug.rb has several advantages:
|
|
11
11
|
* Remote debugging: Support remote debugging natively.
|
12
12
|
* UNIX domain socket
|
13
13
|
* TCP/IP
|
14
|
-
* VSCode/DAP integration (
|
15
|
-
* Extensible: application can introduce debugging support with several
|
14
|
+
* VSCode/DAP integration ([VSCode rdbg Ruby Debugger - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=KoichiSasada.vscode-rdbg))
|
15
|
+
* Extensible: application can introduce debugging support with several ways:
|
16
16
|
* By `rdbg` command
|
17
17
|
* By loading libraries with `-r` command line option
|
18
18
|
* By calling Ruby's method explicitly
|
@@ -20,6 +20,7 @@ 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
|
|
@@ -29,300 +30,373 @@ $ gem install debug --pre
|
|
29
30
|
|
30
31
|
or specify `-Ipath/to/debug/lib` in `RUBYOPT` or each ruby command-line option, especially for debug this gem development.
|
31
32
|
|
32
|
-
|
33
|
+
If you use Bundler, write the following line to your Gemfile.
|
34
|
+
|
35
|
+
```
|
36
|
+
gem "debug", ">= 1.0.0.rc"
|
37
|
+
```
|
38
|
+
|
39
|
+
# HOW TO USE
|
40
|
+
|
41
|
+
To use a debugger, roughly you will do the following steps:
|
42
|
+
|
43
|
+
1. Set breakpoints.
|
44
|
+
2. Run a program with the debugger.
|
45
|
+
3. At the breakpoint, enter the debugger console.
|
46
|
+
4. Use debug commands.
|
47
|
+
* Query the program status (e.g. `p lvar` to see the local variable `lvar`).
|
48
|
+
* Control program flow (e.g. move to the another line with `step`, to the next line with `next`).
|
49
|
+
* Set another breakpoint (e.g. `catch Exception` to set a breakpoint when `Exception` is raised).
|
50
|
+
* Change the configuration (e.g. `config set no_color true` to disable coloring).
|
51
|
+
* Continue the program (`c` or `continue`) and goto 3.
|
52
|
+
|
53
|
+
## Invoke with the debugger
|
54
|
+
|
55
|
+
There are several options for (1) and (2). Please choose your favorite way.
|
56
|
+
|
57
|
+
### Modify source code as `binding.pry` and `binding.irb`
|
58
|
+
|
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`.
|
60
|
+
After that, you run the program as usual and you will enter the debug console at breakpoints you inserted.
|
61
|
+
|
62
|
+
The following example shows the demonstration of `binding.break`.
|
63
|
+
|
64
|
+
```shell
|
65
|
+
$ cat target.rb # Sample program
|
66
|
+
require 'debug'
|
67
|
+
|
68
|
+
a = 1
|
69
|
+
b = 2
|
70
|
+
binding.break # Program will stop here
|
71
|
+
c = 3
|
72
|
+
d = 4
|
73
|
+
binding.break # Program will stop here
|
74
|
+
p [a, b, c, d]
|
75
|
+
|
76
|
+
$ ruby target.rb # Run the program normally.
|
77
|
+
DEBUGGER: Session start (pid: 7604)
|
78
|
+
[1, 10] in target.rb
|
79
|
+
1| require 'debug'
|
80
|
+
2|
|
81
|
+
3| a = 1
|
82
|
+
4| b = 2
|
83
|
+
=> 5| binding.break # Now you can see it stops at this line
|
84
|
+
6| c = 3
|
85
|
+
7| d = 4
|
86
|
+
8| binding.break
|
87
|
+
9| p [a, b, c, d]
|
88
|
+
10|
|
89
|
+
=>#0 <main> at target.rb:5
|
90
|
+
|
91
|
+
(rdbg) info locals # You can show local variables
|
92
|
+
=>#0 <main> at target.rb:5
|
93
|
+
%self => main
|
94
|
+
a => 1
|
95
|
+
b => 2
|
96
|
+
c => nil
|
97
|
+
d => nil
|
98
|
+
|
99
|
+
(rdbg) continue # Continue the execution
|
100
|
+
[3, 11] in target.rb
|
101
|
+
3| a = 1
|
102
|
+
4| b = 2
|
103
|
+
5| binding.break
|
104
|
+
6| c = 3
|
105
|
+
7| d = 4
|
106
|
+
=> 8| binding.break # Again the program stops at here
|
107
|
+
9| p [a, b, c, d]
|
108
|
+
10|
|
109
|
+
11| __END__
|
110
|
+
=>#0 <main> at target.rb:8
|
111
|
+
|
112
|
+
(rdbg) info locals # And you can see the updated local variables
|
113
|
+
=>#0 <main> at target.rb:8
|
114
|
+
%self => main
|
115
|
+
a => 1
|
116
|
+
b => 2
|
117
|
+
c => 3
|
118
|
+
d => 4
|
119
|
+
|
120
|
+
(rdbg) continue
|
121
|
+
[1, 2, 3, 4]
|
122
|
+
```
|
123
|
+
|
124
|
+
### Invoke the program from the debugger as a traditional debuggers
|
125
|
+
|
126
|
+
If you don't want to modify the source code, you can set breakpoints with a debug command `break` (`b` for short).
|
127
|
+
Using `rdbg` command to launch the program without any modifications, you can run the program with the debugger.
|
128
|
+
|
129
|
+
```shell
|
130
|
+
$ cat target.rb # Sample program
|
131
|
+
a = 1
|
132
|
+
b = 2
|
133
|
+
c = 3
|
134
|
+
d = 4
|
135
|
+
p [a, b, c, d]
|
136
|
+
|
137
|
+
$ rdbg target.rb # run like `ruby target.rb`
|
138
|
+
DEBUGGER: Session start (pid: 7656)
|
139
|
+
[1, 7] in target.rb
|
140
|
+
=> 1| a = 1
|
141
|
+
2| b = 2
|
142
|
+
3| c = 3
|
143
|
+
4| d = 4
|
144
|
+
5| p [a, b, c, d]
|
145
|
+
6|
|
146
|
+
7| __END__
|
147
|
+
=>#0 <main> at target.rb:1
|
33
148
|
|
34
|
-
|
149
|
+
(rdbg)
|
150
|
+
```
|
35
151
|
|
36
|
-
|
152
|
+
`rdbg` command suspends the program at the beginning of the given script (`target.rb` in this case) and you can use debug commands. `(rdbg)` is prompt. Let's set breakpoints on line 3 and line 5 with `break` command (`b` for short).
|
37
153
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
* (b-2) Open with TCP/IP port
|
154
|
+
```shell
|
155
|
+
(rdbg) break 3 # set breakpoint at line 3
|
156
|
+
#0 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:3 (line)
|
42
157
|
|
43
|
-
(
|
44
|
-
|
158
|
+
(rdbg) b 5 # set breakpoint at line 5
|
159
|
+
#1 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:5 (line)
|
45
160
|
|
46
|
-
|
161
|
+
(rdbg) break # show all registered breakpoints
|
162
|
+
#0 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:3 (line)
|
163
|
+
#1 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:5 (line)
|
164
|
+
```
|
47
165
|
|
48
|
-
|
49
|
-
* (2) Use `ruby -r debug...` command line option
|
50
|
-
* (3) Write `require 'debug...'` in .rb files
|
166
|
+
You can see that two breakpoints are registered. Let's continue the program by `continue` command.
|
51
167
|
|
52
|
-
|
168
|
+
```shell
|
169
|
+
(rdbg) continue
|
170
|
+
[1, 7] in target.rb
|
171
|
+
1| a = 1
|
172
|
+
2| b = 2
|
173
|
+
=> 3| c = 3
|
174
|
+
4| d = 4
|
175
|
+
5| p [a, b, c, d]
|
176
|
+
6|
|
177
|
+
7| __END__
|
178
|
+
=>#0 <main> at target.rb:3
|
53
179
|
|
54
|
-
|
180
|
+
Stop by #0 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:3 (line)
|
55
181
|
|
56
|
-
|
57
|
-
$ rdbg target.rb
|
58
|
-
$ rdbg -- -r foo -e expr # -- is required to make clear rdbg options and ruby's options
|
182
|
+
(rdbg)
|
59
183
|
```
|
60
184
|
|
61
|
-
|
185
|
+
You can see that we can stop at line 3.
|
186
|
+
Let's see the local variables with `info` command, and continue.
|
187
|
+
You can also confirm that the program will suspend at line 5 and you can use `info` command again.
|
62
188
|
|
63
|
-
```
|
64
|
-
|
65
|
-
|
189
|
+
```shell
|
190
|
+
(rdbg) info
|
191
|
+
=>#0 <main> at target.rb:3
|
192
|
+
%self => main
|
193
|
+
a => 1
|
194
|
+
b => 2
|
195
|
+
c => nil
|
196
|
+
d => nil
|
66
197
|
|
67
|
-
|
198
|
+
(rdbg) continue
|
199
|
+
[1, 7] in target.rb
|
200
|
+
1| a = 1
|
201
|
+
2| b = 2
|
202
|
+
3| c = 3
|
203
|
+
4| d = 4
|
204
|
+
=> 5| p [a, b, c, d]
|
205
|
+
6|
|
206
|
+
7| __END__
|
207
|
+
=>#0 <main> at target.rb:5
|
68
208
|
|
69
|
-
|
70
|
-
# target.rb
|
71
|
-
require 'debug/run' # start the debug console
|
209
|
+
Stop by #1 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:5 (line)
|
72
210
|
|
73
|
-
|
211
|
+
(rdbg) info
|
212
|
+
=>#0 <main> at target.rb:5
|
213
|
+
%self => main
|
214
|
+
a => 1
|
215
|
+
b => 2
|
216
|
+
c => 3
|
217
|
+
d => 4
|
74
218
|
|
75
|
-
|
76
|
-
|
77
|
-
# ... rest of program ...
|
219
|
+
(rdbg) continue
|
220
|
+
[1, 2, 3, 4]
|
78
221
|
```
|
79
222
|
|
80
|
-
|
81
|
-
|
82
|
-
```
|
223
|
+
By the way, using `rdbg` command you can suspend your application with `C-c` (SIGINT) and enter the debug console.
|
224
|
+
It will help that if you want to know what the program is doing.
|
83
225
|
|
84
|
-
|
85
|
-
The debuggee program (`target.rb`) is suspended at the beginning of `target.rb`.
|
226
|
+
### Use `rdbg` with commands written in Ruby
|
86
227
|
|
87
|
-
|
88
|
-
You can suspend the debuggee program and show the debug console with `Ctrl-C`.
|
228
|
+
If you want to run a command written in Ruby like like `rake`, `rails`, `bundle`, `rspec` and so on, you can use `rdbg -c` option.
|
89
229
|
|
90
|
-
|
230
|
+
* Without `-c` option, `rdbg <name>` means that `<name>` is Ruby script and invoke it like `ruby <name>` with the debugger.
|
231
|
+
* With `-c` option, `rdbg -c <name>` means that `<name>` is command in `PATH` and simply invoke it with the debugger.
|
91
232
|
|
92
|
-
|
93
|
-
|
233
|
+
Examples:
|
234
|
+
* `rdbg -c -- rails server`
|
235
|
+
* `rdbg -c -- bundle exec ruby foo.rb`
|
236
|
+
* `rdbg -c -- bundle exec rake test`
|
237
|
+
* `rdbg -c -- ruby target.rb` is same as `rdbg target.rb`
|
94
238
|
|
95
|
-
|
96
|
-
=> 1| a = 1
|
97
|
-
2| b = 2
|
98
|
-
3| c = 3
|
99
|
-
4| p [a + b + c]
|
100
|
-
5|
|
101
|
-
--> #0 /home/ko1/src/rb/target.rb:1:in `<main>'
|
239
|
+
NOTE: `--` is needed to separate the command line options for `rdbg` and invoking command. For example, `rdbg -c rake -T` is recognized like `rdbg -c -T -- rake`. It should be `rdbg -c -- rake -T`.
|
102
240
|
|
103
|
-
(
|
104
|
-
%self => main
|
105
|
-
a => nil
|
106
|
-
b => nil
|
107
|
-
c => nil
|
241
|
+
NOTE: If you want to use bundler (`bundle` command), you need to write `gem debug` line in your `Gemfile`.
|
108
242
|
|
109
|
-
|
110
|
-
=> nil
|
243
|
+
### Using VSCode
|
111
244
|
|
112
|
-
|
245
|
+
Like other languages, you can use this debugger on the VSCode.
|
113
246
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
--> #0 /home/ko1/src/rb/target.rb:2:in `<main>'
|
247
|
+
1. Install [VSCode rdbg Ruby Debugger - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=KoichiSasada.vscode-rdbg)
|
248
|
+
2. Open `.rb` file (e.g. `target.rb`)
|
249
|
+
3. Register breakpoints with "Toggle breakpoint" in Run menu (or type F9 key)
|
250
|
+
4. Choose "Start debugging" in "Run" menu (or type F5 key)
|
251
|
+
5. You will see a dialog "Debug command line" and you can choose your favorite command line your want to run.
|
252
|
+
6. Chosen command line is invoked with `rdbg -c` and VSCode shows the details at breakpoints.
|
121
253
|
|
122
|
-
|
254
|
+
Please refer [Debugging in Visual Studio Code](https://code.visualstudio.com/docs/editor/debugging) for operations on VSCode.
|
123
255
|
|
124
|
-
|
125
|
-
|
126
|
-
2| b = 2
|
127
|
-
=> 3| c = 3
|
128
|
-
4| p [a + b + c]
|
129
|
-
5|
|
130
|
-
--> #0 /home/ko1/src/rb/target.rb:3:in `<main>'
|
256
|
+
You can configure the extension in `.vscode/launch.json`.
|
257
|
+
Please see the extension page for more details.
|
131
258
|
|
132
|
-
|
259
|
+
## Remote debugging
|
133
260
|
|
134
|
-
|
135
|
-
1| a = 1
|
136
|
-
2| b = 2
|
137
|
-
3| c = 3
|
138
|
-
=> 4| p [a + b + c]
|
139
|
-
5|
|
140
|
-
--> #0 /home/ko1/src/rb/target.rb:4:in `<main>'
|
141
|
-
|
142
|
-
(rdbg) info # Show all local variables
|
143
|
-
%self => main
|
144
|
-
a => 1
|
145
|
-
b => 2
|
146
|
-
c => 3
|
147
|
-
|
148
|
-
(rdbg) c # Continue the program ("c" is a short name of "continue")
|
149
|
-
[6]
|
150
|
-
```
|
261
|
+
You can use this debugger as a remote debugger. For example, it will help the following situations:
|
151
262
|
|
152
|
-
|
263
|
+
* Your application does not run on TTY and it is hard to use `binding.pry` or `binding.irb`.
|
264
|
+
* Your application is running on Docker container and there is no TTY.
|
265
|
+
* Your application is running as a daemon.
|
266
|
+
* Your application uses pipe for STDIN or STDOUT.
|
267
|
+
* Your application is running as a daemon and you want to query the running status (checking a backtrace and so on).
|
153
268
|
|
154
|
-
|
269
|
+
You can run your application as a remote debuggee and the remote debugger console can attach to the debuggee anytime.
|
155
270
|
|
156
|
-
|
157
|
-
$ rdbg --open target.rb # or rdbg -O target.rb for shorthand
|
158
|
-
Debugger can attach via UNIX domain socket (/home/ko1/.ruby-debug-sock/ruby-debug-ko1-5042)
|
159
|
-
```
|
271
|
+
### Invoke as a remote debuggee
|
160
272
|
|
161
|
-
|
273
|
+
There are two ways to invoke a script as remote debuggee: Use `rdbg --open` and require `debug/open` (or `debug/open_nonstop`).
|
162
274
|
|
163
|
-
|
164
|
-
$ ruby -r debug/open target.rb
|
165
|
-
Debugger can attach via UNIX domain socket (/home/ko1/.ruby-debug-sock/ruby-debug-ko1-5042)
|
166
|
-
```
|
275
|
+
#### `rdbg --open` (or `rdbg -O` for short)
|
167
276
|
|
168
|
-
|
277
|
+
You can run a script with `rdbg --open target.rb` command and run a `target.rb` as a debuggee program. It also opens the network port and suspends at the beginning of `target.rb`.
|
169
278
|
|
170
|
-
```
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
require 'debug/server' # introduce remote debugging feature
|
177
|
-
DEBUGGER__.open # open the debugger entry point by UNIX domain socket.
|
178
|
-
# or DEBUGGER__.open_unix to specify UNIX domain socket.
|
179
|
-
```
|
180
|
-
|
181
|
-
```
|
182
|
-
$ ruby target.rb
|
183
|
-
Debugger can attach via UNIX domain socket (/home/ko1/.ruby-debug-sock/ruby-debug-ko1-5042)
|
279
|
+
```shell
|
280
|
+
$ exe/rdbg --open target.rb
|
281
|
+
DEBUGGER: Session start (pid: 7773)
|
282
|
+
DEBUGGER: Debugger can attach via UNIX domain socket (/home/ko1/.ruby-debug-sock/ruby-debug-ko1-7773)
|
283
|
+
DEBUGGER: wait for debugger connection...
|
184
284
|
```
|
185
285
|
|
186
|
-
|
187
|
-
The debuggee process waits for debugger connection at the beginning of `target.rb` like that:
|
286
|
+
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).
|
188
287
|
|
189
|
-
|
190
|
-
$ rdbg -O ~/src/rb/target.rb
|
191
|
-
DEBUGGER: Debugger can attach via UNIX domain socket (/home/ko1/.ruby-debug-sock/ruby-debug-ko1-29828)
|
192
|
-
DEBUGGER: wait for debugger connection...
|
193
|
-
```
|
288
|
+
You can connect to the debuggee with `rdbg --attach` command (`rdbg -A` for short).
|
194
289
|
|
195
|
-
|
290
|
+
```shell
|
291
|
+
$ rdbg -A
|
292
|
+
[1, 7] in target.rb
|
293
|
+
=> 1| a = 1
|
294
|
+
2| b = 2
|
295
|
+
3| c = 3
|
296
|
+
4| d = 4
|
297
|
+
5| p [a, b, c, d]
|
298
|
+
6|
|
299
|
+
7| __END__
|
300
|
+
=>#0 <main> at target.rb:1
|
196
301
|
|
197
|
-
|
198
|
-
$ rdbg --attach # or rdbg -A for shorthand
|
199
|
-
|
200
|
-
[1, 4] in /home/ko1/src/rb/target.rb
|
201
|
-
1| (1..).each do |i|
|
202
|
-
=> 2| sleep 0.5
|
203
|
-
3| p i
|
204
|
-
4| end
|
205
|
-
--> #0 [C] /home/ko1/src/rb/target.rb:2:in `sleep'
|
206
|
-
#1 /home/ko1/src/rb/target.rb:2:in `block in <main>' {|i=17|}
|
207
|
-
#2 [C] /home/ko1/src/rb/target.rb:1:in `each'
|
208
|
-
# and 1 frames (use `bt' command for all frames)
|
209
|
-
|
210
|
-
(rdb)
|
302
|
+
(rdbg:remote)
|
211
303
|
```
|
212
304
|
|
213
|
-
|
305
|
+
If there is no other opening ports on the default directory, `rdbg --attach` command chooses the only one opening UNIX domain socket and connect to it. If there are more files, you need to specify the file.
|
214
306
|
|
215
|
-
|
216
|
-
You can re-connect to the debuggee process by `rdbg -A` command again, and the debuggee process suspends the execution (and debugger can input any debug commands).
|
307
|
+
When `rdbg --attach` connects to the debuggee, you can use any debug commands (set breakpoints, continue the program and so on) like local debug console. When an debuggee program exits, the remote console will also terminate.
|
217
308
|
|
218
|
-
If you
|
309
|
+
NOTE: If you use `quit` command, only remote console exits and the debuggee program continues to run (and you can connect it again). If you want to exit the debuggee program, use `kill` command.
|
219
310
|
|
220
|
-
|
221
|
-
* Set the environment variable `RUBY_DEBUG_NONSTOP=1`
|
311
|
+
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`.
|
222
312
|
|
223
|
-
|
313
|
+
To connect to the debuggee, you need to specify the port.
|
224
314
|
|
225
|
-
```
|
226
|
-
$ rdbg --attach
|
227
|
-
Please select a debug session:
|
228
|
-
ruby-debug-ko1-19638
|
229
|
-
ruby-debug-ko1-19603
|
315
|
+
```shell
|
316
|
+
$ rdbg --attach 12345
|
230
317
|
```
|
231
318
|
|
232
|
-
|
233
|
-
|
234
|
-
```
|
235
|
-
$ rdbg --attach ruby-debug-ko1-19638
|
236
|
-
```
|
319
|
+
If you want to choose the host to bind, you can use `--host` option.
|
320
|
+
Note that all messages communicated between the debugger and the debuggee are *NOT* encrypted so please use remote debugging carefully.
|
237
321
|
|
238
|
-
|
239
|
-
* `RUBY_DEBUG_SOCK_DIR` environment variable if available.
|
240
|
-
* `XDG_RUNTIME_DIR` environment variable if available.
|
241
|
-
* `$HOME/.ruby-debug-sock` if `$HOME` is available.
|
322
|
+
#### `require 'debug/open'` in a program
|
242
323
|
|
243
|
-
|
324
|
+
If you can modify the program, you can open debugging port by adding `require 'debug/open'` line in the program.
|
244
325
|
|
245
|
-
|
326
|
+
If you don't want to stop the program at the beginning, you can also use `require 'debug/open_nonstop'`.
|
327
|
+
Using `debug/open_nonstop` is useful if you want to open a backdoor to the application.
|
328
|
+
However, it is also danger because it can become another vulnerability.
|
329
|
+
Please use it carefully.
|
246
330
|
|
247
|
-
|
331
|
+
By default, UNIX domain socket is used for the debugging port. To use TCP/IP, you can set the `RUBY_DEBUG_PORT` environment variable.
|
248
332
|
|
249
|
-
```
|
250
|
-
$
|
251
|
-
# or
|
252
|
-
$ rdbg --open --port=12345 target.rb
|
253
|
-
Debugger can attach via TCP/IP (localhost:12345)
|
333
|
+
```shell
|
334
|
+
$ RUBY_DEBUG_PORT=12345 ruby target.rb
|
254
335
|
```
|
255
336
|
|
256
|
-
|
337
|
+
## Configuration
|
257
338
|
|
339
|
+
You can configure the debugger's behavior with debug commands and environment variables.
|
340
|
+
When the debug session is started, initial scripts are loaded so you can put your favorite configurations in the initial scripts.
|
258
341
|
|
259
|
-
|
260
|
-
$ RUBY_DEBUG_PORT=12345 ruby -r debug/open target.rb
|
261
|
-
Debugger can attach via TCP/IP (localhost:12345)
|
262
|
-
```
|
342
|
+
### Configuration list
|
263
343
|
|
264
|
-
|
344
|
+
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.
|
265
345
|
|
266
|
-
```ruby
|
267
|
-
# target.rb
|
268
|
-
require 'debug/open' # open the debugger entry point.
|
269
346
|
```
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
```
|
274
|
-
$ RUBY_DEBUG_PORT=12345 ruby target.rb
|
275
|
-
Debugger can attach via TCP/IP (localhost:12345)
|
347
|
+
# configuration example
|
348
|
+
config set log_level INFO
|
349
|
+
config set no_color true
|
276
350
|
```
|
277
351
|
|
278
|
-
or
|
279
352
|
|
280
|
-
```ruby
|
281
|
-
# target.rb
|
282
|
-
require 'debug/server' # introduce remote debugging feature
|
283
|
-
DEBUGGER__.open(port: 12345)
|
284
|
-
# or DEBUGGER__.open_tcp(port: 12345)
|
285
|
-
```
|
286
353
|
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
354
|
+
* UI
|
355
|
+
* `RUBY_DEBUG_LOG_LEVEL` (`log_level`): Log level same as Logger (default: WARN)
|
356
|
+
* `RUBY_DEBUG_SHOW_SRC_LINES` (`show_src_lines`): Show n lines source code on breakpoint (default: 10 lines)
|
357
|
+
* `RUBY_DEBUG_SHOW_FRAMES` (`show_frames`): Show n frames on breakpoint (default: 2 frames)
|
358
|
+
* `RUBY_DEBUG_USE_SHORT_PATH` (`use_short_path`): Show shoten PATH (like $(Gem)/foo.rb)
|
359
|
+
* `RUBY_DEBUG_NO_COLOR` (`no_color`): Do not use colorize (default: false)
|
360
|
+
* `RUBY_DEBUG_NO_SIGINT_HOOK` (`no_sigint_hook`): Do not suspend on SIGINT (default: false)
|
361
|
+
* `RUBY_DEBUG_NO_RELINE` (`no_reline`): Do not use Reline library (default: false)
|
291
362
|
|
292
|
-
|
363
|
+
* CONTROL
|
364
|
+
* `RUBY_DEBUG_SKIP_PATH` (`skip_path`): Skip showing/entering frames for given paths (default: [])
|
365
|
+
* `RUBY_DEBUG_SKIP_NOSRC` (`skip_nosrc`): Skip on no source code lines (default: false)
|
366
|
+
* `RUBY_DEBUG_KEEP_ALLOC_SITE` (`keep_alloc_site`): Keep allocation site and p, pp shows it (default: false)
|
367
|
+
* `RUBY_DEBUG_POSTMORTEM` (`postmortem`): Enable postmortem debug (default: false)
|
368
|
+
* `RUBY_DEBUG_PARENT_ON_FORK` (`parent_on_fork`): Keep debugging parent process on fork (default: false)
|
369
|
+
* `RUBY_DEBUG_SIGDUMP_SIG` (`sigdump_sig`): Sigdump signal (default: disabled)
|
293
370
|
|
294
|
-
|
371
|
+
* BOOT
|
372
|
+
* `RUBY_DEBUG_NONSTOP` (`nonstop`): Nonstop mode
|
373
|
+
* `RUBY_DEBUG_INIT_SCRIPT` (`init_script`): debug command script path loaded at first stop
|
374
|
+
* `RUBY_DEBUG_COMMANDS` (`commands`): debug commands invoked at first stop. commands should be separated by ';;'
|
375
|
+
* `RUBY_DEBUG_NO_RC` (`no_rc`): ignore loading ~/.rdbgrc(.rb)
|
295
376
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
377
|
+
* REMOTE
|
378
|
+
* `RUBY_DEBUG_PORT` (`port`): TCP/IP remote debugging: port
|
379
|
+
* `RUBY_DEBUG_HOST` (`host`): TCP/IP remote debugging: host (localhost if not given)
|
380
|
+
* `RUBY_DEBUG_SOCK_PATH` (`sock_path`): UNIX Domain Socket remote debugging: socket path
|
381
|
+
* `RUBY_DEBUG_SOCK_DIR` (`sock_dir`): UNIX Domain Socket remote debugging: socket directory
|
382
|
+
* `RUBY_DEBUG_COOKIE` (`cookie`): Cookie for negotiation
|
300
383
|
|
301
384
|
### Initial scripts
|
302
385
|
|
303
|
-
If there
|
304
|
-
|
305
|
-
Initial scripts are evaluated at the first suspend timing (generally, it is the beginning of the target script). For example, you can set break points with `break file:123`.
|
386
|
+
If there is `~/.rdbgrc`, the file is loaded as an initial script (which contains debug commands) when the debug session is started.
|
306
387
|
|
307
|
-
|
388
|
+
* `RUBY_DEBUG_INIT_SCRIPT` environment variable can specify the initial script file.
|
389
|
+
* You can specify the initial script with `rdbg -x initial_script` (like gdb's `-x` option).
|
308
390
|
|
309
|
-
|
391
|
+
Initial scripts are useful to write your favorite configurations.
|
392
|
+
For example, you can set break points with `break file:123` in `~/.rdbgrc`.
|
310
393
|
|
311
|
-
|
312
|
-
|
313
|
-
* `RUBY_DEBUG_NONSTOP`: 1 for nonstop at the beginning of program.
|
314
|
-
* `RUBY_DEBUG_INIT_SCRIPT`: Initial script path loaded at the first stop.
|
315
|
-
* `RUBY_DEBUG_COMMANDS`: Debug commands invoked at the first stop. Commands should be separated by ';;'.
|
316
|
-
* `RUBY_DEBUG_SHOW_SRC_LINES`: Show n lines source code on breakpoint (default: 10 lines).
|
317
|
-
* `RUBY_DEBUG_SHOW_FRAMES`: Show n frames on breakpoint (default: 2 frames).
|
318
|
-
* Remote debugging
|
319
|
-
* `RUBY_DEBUG_PORT`: TCP/IP remote debugging: port to open.
|
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.
|
322
|
-
* `RUBY_DEBUG_SOCK_DIR`: UNIX Domain Socket remote debugging: socket directory to open.
|
394
|
+
If there are `~/.rdbgrc.rb` is available, it is also loaded as a ruby script at same timing.
|
323
395
|
|
324
396
|
## Debug command on the debug console
|
325
397
|
|
398
|
+
On the debug console, you can use the following debug commands.
|
399
|
+
|
326
400
|
* `Enter` repeats the last command (useful when repeating `step`s).
|
327
401
|
* `Ctrl-D` is equal to `quit` command.
|
328
402
|
* [debug command compare sheet - Google Sheets](https://docs.google.com/spreadsheets/d/1TlmmUDsvwK4sSIyoMv-io52BUUz__R5wpu-ComXlsw0/edit?usp=sharing)
|
@@ -335,10 +409,16 @@ The `<...>` notation means the argument.
|
|
335
409
|
|
336
410
|
* `s[tep]`
|
337
411
|
* Step in. Resume the program until next breakable point.
|
412
|
+
* `s[tep] <n>`
|
413
|
+
* Step in, resume the program at `<n>`th breakable point.
|
338
414
|
* `n[ext]`
|
339
415
|
* Step over. Resume the program until next line.
|
416
|
+
* `n[ext] <n>`
|
417
|
+
* Step over, same as `step <n>`.
|
340
418
|
* `fin[ish]`
|
341
419
|
* Finish this frame. Resume the program until the current frame is finished.
|
420
|
+
* `fin[ish] <n>`
|
421
|
+
* Finish frames, same as `step <n>`.
|
342
422
|
* `c[ontinue]`
|
343
423
|
* Resume the program.
|
344
424
|
* `q[uit]` or `Ctrl-D`
|
@@ -362,10 +442,14 @@ The `<...>` notation means the argument.
|
|
362
442
|
* Set breakpoint on the method `<class>#<name>`.
|
363
443
|
* `b[reak] <expr>.<name>`
|
364
444
|
* Set breakpoint on the method `<expr>.<name>`.
|
365
|
-
* `b[reak] ... if <expr>`
|
445
|
+
* `b[reak] ... if: <expr>`
|
366
446
|
* break if `<expr>` is true at specified location.
|
367
|
-
* `b[reak]
|
368
|
-
* break
|
447
|
+
* `b[reak] ... pre: <command>`
|
448
|
+
* break and run `<command>` before stopping.
|
449
|
+
* `b[reak] ... do: <command>`
|
450
|
+
* break and run `<command>`, and continue.
|
451
|
+
* `b[reak] if: <expr>`
|
452
|
+
* break if: `<expr>` is true at any lines.
|
369
453
|
* Note that this feature is super slow.
|
370
454
|
* `catch <Error>`
|
371
455
|
* Set breakpoint on raising `<Error>`.
|
@@ -381,6 +465,12 @@ The `<...>` notation means the argument.
|
|
381
465
|
|
382
466
|
* `bt` or `backtrace`
|
383
467
|
* Show backtrace (frame) information.
|
468
|
+
* `bt <num>` or `backtrace <num>`
|
469
|
+
* Only shows first `<num>` frames.
|
470
|
+
* `bt /regexp/` or `backtrace /regexp/`
|
471
|
+
* Only shows frames with method name or location info that matches `/regexp/`.
|
472
|
+
* `bt <num> /regexp/` or `backtrace <num> /regexp/`
|
473
|
+
* Only shows first `<num>` frames with method name or location info that matches `/regexp/`.
|
384
474
|
* `l[ist]`
|
385
475
|
* Show current frame's source code.
|
386
476
|
* Next `list` command shows the successor lines.
|
@@ -393,11 +483,26 @@ The `<...>` notation means the argument.
|
|
393
483
|
* Note that edited file will not be reloaded.
|
394
484
|
* `edit <file>`
|
395
485
|
* Open <file> on the editor.
|
396
|
-
* `i[nfo]
|
486
|
+
* `i[nfo]`
|
487
|
+
* Show information about current frame (local/instance variables and defined constants).
|
488
|
+
* `i[nfo] l[ocal[s]]`
|
397
489
|
* Show information about the current frame (local variables)
|
398
490
|
* It includes `self` as `%self` and a return value as `%return`.
|
491
|
+
* `i[nfo] i[var[s]]` or `i[nfo] instance`
|
492
|
+
* Show information about insttance variables about `self`.
|
493
|
+
* `i[nfo] c[onst[s]]` or `i[nfo] constant[s]`
|
494
|
+
* Show information about accessible constants except toplevel constants.
|
495
|
+
* `i[nfo] g[lobal[s]]`
|
496
|
+
* Show information about global variables
|
497
|
+
* `i[nfo] ... </pattern/>`
|
498
|
+
* Filter the output with `</pattern/>`.
|
399
499
|
* `i[nfo] th[read[s]]`
|
400
500
|
* Show all threads (same as `th[read]`).
|
501
|
+
* `o[utline]` or `ls`
|
502
|
+
* Show you available methods, constants, local variables, and instance variables in the current scope.
|
503
|
+
* `o[utline] <expr>` or `ls <expr>`
|
504
|
+
* Show you available methods and instance variables of the given object.
|
505
|
+
* If the object is a class/module, it also lists its constants.
|
401
506
|
* `display`
|
402
507
|
* Show display setting.
|
403
508
|
* `display <expr>`
|
@@ -406,8 +511,6 @@ The `<...>` notation means the argument.
|
|
406
511
|
* Remove all display settings.
|
407
512
|
* `undisplay <displaynum>`
|
408
513
|
* Remove a specified display setting.
|
409
|
-
* `trace [on|off]`
|
410
|
-
* enable or disable line tracer.
|
411
514
|
|
412
515
|
### Frame control
|
413
516
|
|
@@ -431,6 +534,36 @@ The `<...>` notation means the argument.
|
|
431
534
|
* `irb`
|
432
535
|
* Invoke `irb` on the current frame.
|
433
536
|
|
537
|
+
### Trace
|
538
|
+
|
539
|
+
* `trace`
|
540
|
+
* Show available tracers list.
|
541
|
+
* `trace line`
|
542
|
+
* Add a line tracer. It indicates line events.
|
543
|
+
* `trace call`
|
544
|
+
* Add a call tracer. It indicate call/return events.
|
545
|
+
* `trace exception`
|
546
|
+
* Add an exception tracer. It indicates raising exceptions.
|
547
|
+
* `trace object <expr>`
|
548
|
+
* Add an object tracer. It indicates that an object by `<expr>` is passed as a parameter or a receiver on method call.
|
549
|
+
* `trace ... </pattern/>`
|
550
|
+
* Indicates only matched events to `</pattern/>` (RegExp).
|
551
|
+
* `trace ... into: <file>`
|
552
|
+
* Save trace information into: `<file>`.
|
553
|
+
* `trace off <num>`
|
554
|
+
* Disable tracer specified by `<num>` (use `trace` command to check the numbers).
|
555
|
+
* `trace off [line|call|pass]`
|
556
|
+
* Disable all tracers. If `<type>` is provided, disable specified type tracers.
|
557
|
+
* `record`
|
558
|
+
* Show recording status.
|
559
|
+
* `record [on|off]`
|
560
|
+
* Start/Stop recording.
|
561
|
+
* `step back`
|
562
|
+
* Start replay. Step back with the last execution log.
|
563
|
+
* `s[tep]` does stepping forward with the last log.
|
564
|
+
* `step reset`
|
565
|
+
* Stop replay .
|
566
|
+
|
434
567
|
### Thread control
|
435
568
|
|
436
569
|
* `th[read]`
|
@@ -438,6 +571,21 @@ The `<...>` notation means the argument.
|
|
438
571
|
* `th[read] <thnum>`
|
439
572
|
* Switch thread specified by `<thnum>`.
|
440
573
|
|
574
|
+
### Configuration
|
575
|
+
|
576
|
+
* `config`
|
577
|
+
* Show all configuration with description.
|
578
|
+
* `config <name>`
|
579
|
+
* Show current configuration of <name>.
|
580
|
+
* `config set <name> <val>` or `config <name> = <val>`
|
581
|
+
* Set <name> to <val>.
|
582
|
+
* `config append <name> <val>` or `config <name> << <val>`
|
583
|
+
* Append `<val>` to `<name>` if it is an array.
|
584
|
+
* `config unset <name>`
|
585
|
+
* Set <name> to default.
|
586
|
+
* `source <file>`
|
587
|
+
* Evaluate lines in `<file>` as debug commands.
|
588
|
+
|
441
589
|
### Help
|
442
590
|
|
443
591
|
* `h[elp]`
|
@@ -446,6 +594,83 @@ The `<...>` notation means the argument.
|
|
446
594
|
* Show help for the given command.
|
447
595
|
|
448
596
|
|
597
|
+
## Debugger API
|
598
|
+
|
599
|
+
### Start debugging
|
600
|
+
|
601
|
+
#### Start by requiring a library
|
602
|
+
|
603
|
+
You can start debugging without `rdbg` command by requiring the following libraries:
|
604
|
+
|
605
|
+
* `require 'debug'`: Same as `rdbg --nonstop --no-sigint-hook`.
|
606
|
+
* `require 'debug/start'`: Same as `rdbg`.
|
607
|
+
* `require 'debug/open'`: Same as `rdbg --open`.
|
608
|
+
* `require 'debug/open_nonstop'`: Same as `rdbg --open --nonstop`.
|
609
|
+
|
610
|
+
You need to require one of them at the very beginning of the application.
|
611
|
+
Using `ruby -r` (for example `ruby -r debug/start target.rb`) is another way to invoke with debugger.
|
612
|
+
|
613
|
+
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:
|
614
|
+
|
615
|
+
```shell
|
616
|
+
$ ruby -r debug -e0
|
617
|
+
.../2.7.3/lib/ruby/2.7.0/x86_64-linux/continuation.so: warning: callcc is obsolete; use Fiber instead
|
618
|
+
Debug.rb
|
619
|
+
Emacs support available.
|
620
|
+
|
621
|
+
.../2.7.3/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:162: if RUBYGEMS_ACTIVATION_MONITOR.respond_to?(:mon_owned?)
|
622
|
+
(rdb:1)
|
623
|
+
```
|
624
|
+
|
625
|
+
`lib/debug.rb` was not maintained well in recent years, and the purpose of this library is to rewrite old `lib/debug.rb` with recent techniques.
|
626
|
+
|
627
|
+
#### Start by method
|
628
|
+
|
629
|
+
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.
|
630
|
+
|
631
|
+
* `DEBUGGER__.start(**kw)`: start debug session with local console.
|
632
|
+
* `DEBUGGER__.open(**kw)`: open debug port with configuration (without configurations open with UNIX domain socket)
|
633
|
+
* `DEBUGGER__.open_unix(**kw)`: open debug port with UNIX domain socket
|
634
|
+
* `DEBUGGER__.open_tcp(**kw)`: open debug port with TCP/IP
|
635
|
+
|
636
|
+
For example:
|
637
|
+
|
638
|
+
```ruby
|
639
|
+
require 'debug/session'
|
640
|
+
DEBUGGER__.start(no_color: true, # disable colorize
|
641
|
+
log_level: 'INFO') # Change log_level to INFO
|
642
|
+
|
643
|
+
... # your application code
|
644
|
+
```
|
645
|
+
|
646
|
+
### `binding.break` method
|
647
|
+
|
648
|
+
`binding.break` (or `binding.b`) set breakpoints at written line. It also has several keywords.
|
649
|
+
|
650
|
+
If `do: 'command'` is specified, the debugger suspends the program and run the `command` as a debug command and continue the program.
|
651
|
+
It is useful if you only want to call a debug command and don't want to stop there.
|
652
|
+
|
653
|
+
```
|
654
|
+
def initialize
|
655
|
+
@a = 1
|
656
|
+
binding.b do: 'watch @a'
|
657
|
+
end
|
658
|
+
```
|
659
|
+
|
660
|
+
On this case, register a watch breakpoint for `@a` and continue to run.
|
661
|
+
|
662
|
+
If `pre: 'command'` is specified, the debugger suspends the program and run the `command` as a debug command, and keep suspend.
|
663
|
+
It is useful if you have operations before suspend.
|
664
|
+
|
665
|
+
```
|
666
|
+
def foo
|
667
|
+
binding.b pre: 'p bar()'
|
668
|
+
...
|
669
|
+
end
|
670
|
+
```
|
671
|
+
|
672
|
+
On this case, you can see the result of `bar()` every time you stop there.
|
673
|
+
|
449
674
|
## rdbg command help
|
450
675
|
|
451
676
|
```
|
@@ -453,13 +678,19 @@ exe/rdbg [options] -- [debuggee options]
|
|
453
678
|
|
454
679
|
Debug console mode:
|
455
680
|
-n, --nonstop Do not stop at the beginning of the script.
|
456
|
-
-e
|
457
|
-
-x, --init-script=FILE
|
681
|
+
-e DEBUG_COMMAND Execute debug command at the beginning of the script.
|
682
|
+
-x, --init-script=FILE Execute debug command in the FILE.
|
683
|
+
--no-rc Ignore ~/.rdbgrc
|
684
|
+
--no-color Disable colorize
|
685
|
+
--no-sigint-hook Disable to trap SIGINT
|
686
|
+
-c, --command Enable command mode.
|
687
|
+
The first argument should be a command name in $PATH.
|
688
|
+
Example: 'rdbg -c bundle exec rake test'
|
458
689
|
|
459
690
|
-O, --open Start remote debugging with opening the network port.
|
460
691
|
If TCP/IP options are not given,
|
461
692
|
a UNIX domain socket will be used.
|
462
|
-
--sock-path=SOCK_PATH UNIX
|
693
|
+
--sock-path=SOCK_PATH UNIX Domain socket path
|
463
694
|
--port=PORT Listening TCP/IP port
|
464
695
|
--host=HOST Listening TCP/IP host
|
465
696
|
--cookie=COOKIE Set a cookie for connection
|
@@ -468,6 +699,9 @@ Debug console mode:
|
|
468
699
|
|
469
700
|
'rdbg target.rb foo bar' starts like 'ruby target.rb foo bar'.
|
470
701
|
'rdbg -- -r foo -e bar' starts like 'ruby -r foo -e bar'.
|
702
|
+
'rdbg -c rake test' starts like 'rake test'.
|
703
|
+
'rdbg -c -- rake test -t' starts like 'rake test -t'.
|
704
|
+
'rdbg -c bundle exec rake test' starts like 'bundle exec rake test'.
|
471
705
|
'rdbg -O target.rb foo bar' starts and accepts attaching with UNIX domain socket.
|
472
706
|
'rdbg -O --port 1234 target.rb foo bar' starts accepts attaching with TCP/IP localhost:1234.
|
473
707
|
'rdbg -O --port 1234 -- -r foo -e bar' starts accepts attaching with TCP/IP localhost:1234.
|
@@ -486,7 +720,6 @@ Attach mode:
|
|
486
720
|
|
487
721
|
Other options:
|
488
722
|
-h, --help Print help
|
489
|
-
-c, --command Command mode (first argument is command name)
|
490
723
|
--util=NAME Utility mode (used by tools)
|
491
724
|
|
492
725
|
NOTE
|
@@ -498,6 +731,7 @@ NOTE
|
|
498
731
|
# Contributing
|
499
732
|
|
500
733
|
Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/debug.
|
734
|
+
This debugger is not mature so your feedback will help us.
|
501
735
|
|
502
736
|
Please also check the [contributing guideline](/CONTRIBUTING.md).
|
503
737
|
|