debug 1.0.0.beta6 → 1.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +108 -106
- data/Gemfile +1 -0
- data/README.md +452 -226
- data/Rakefile +2 -1
- data/TODO.md +0 -6
- data/debug.gemspec +1 -0
- data/exe/rdbg +4 -7
- data/ext/debug/debug.c +11 -1
- data/lib/debug/breakpoint.rb +96 -63
- data/lib/debug/client.rb +8 -12
- data/lib/debug/color.rb +25 -6
- data/lib/debug/config.rb +376 -154
- data/lib/debug/console.rb +75 -66
- data/lib/debug/frame_info.rb +40 -7
- data/lib/debug/local.rb +91 -0
- data/lib/debug/open.rb +1 -1
- data/lib/debug/open_nonstop.rb +15 -0
- data/lib/debug/server.rb +74 -30
- data/lib/debug/server_dap.rb +32 -7
- data/lib/debug/session.rb +729 -319
- data/lib/debug/{run.rb → start.rb} +1 -1
- data/lib/debug/thread_client.rb +651 -156
- data/lib/debug/tracer.rb +242 -0
- data/lib/debug/version.rb +1 -1
- data/misc/README.md.erb +338 -217
- metadata +20 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 253c51808e29545d8954144abc1a821b1a795e18f56a9521840d368dcf09b63b
|
4
|
+
data.tar.gz: 40b9bc722ce6dd5b1cfa2d0617f97302b5127fd84dd12e17afd6f1b2a69a3058
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc6192ec83e3eee164d26a5958c7dd4fede162d42f5824b5922847986b6e9f6ba00dba92ceb7789de36bf5954a53974a3e1d7d509cc304fe260a8459a395aba2
|
7
|
+
data.tar.gz: f3835f17d28780d2abf16943891ad189dfb17de7c44fba72115e6ee24b04b6eab321b702cf8bd93965e70464590d5d0c20d9f4a9f3cba08a63551491c9e7b195
|
data/CONTRIBUTING.md
CHANGED
@@ -49,75 +49,75 @@ $ bin/gentest target.rb
|
|
49
49
|
#### 3. Debugger will be executed. You can type any debug commands.
|
50
50
|
```shell
|
51
51
|
$ bin/gentest target.rb
|
52
|
+
DEBUGGER: Session start (pid: 11139)
|
52
53
|
[1, 9] in ~/workspace/debug/target.rb
|
53
|
-
=>
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
62
63
|
=>#0 <main> at ~/workspace/debug/target.rb:1
|
63
64
|
INTERNAL_INFO: {"location":"~/workspace/debug/target.rb:1","line":1}
|
64
|
-
|
65
65
|
(rdbg)s
|
66
66
|
s
|
67
67
|
[1, 9] in ~/workspace/debug/target.rb
|
68
|
-
|
69
|
-
=>
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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
77
|
=>#0 <module:Foo> at ~/workspace/debug/target.rb:2
|
78
78
|
#1 <main> at ~/workspace/debug/target.rb:1
|
79
79
|
INTERNAL_INFO: {"location":"~/workspace/debug/target.rb:2","line":2}
|
80
|
-
|
81
80
|
(rdbg)n
|
82
81
|
n
|
83
82
|
[1, 9] in ~/workspace/debug/target.rb
|
84
|
-
|
85
|
-
|
86
|
-
=>
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
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
|
93
92
|
=>#0 <class:Bar> at ~/workspace/debug/target.rb:3
|
94
93
|
#1 <module:Foo> at ~/workspace/debug/target.rb:2
|
95
|
-
#
|
94
|
+
# and 1 frames (use `bt' command for all frames)
|
96
95
|
INTERNAL_INFO: {"location":"~/workspace/debug/target.rb:3","line":3}
|
97
|
-
|
98
96
|
(rdbg)b 7
|
99
97
|
b 7
|
98
|
+
#0 BP - Line /Users/naotto/workspace/debug/target.rb:7 (line)
|
100
99
|
INTERNAL_INFO: {"location":"~/workspace/debug/target.rb:3","line":3}
|
101
|
-
|
102
100
|
(rdbg)c
|
103
101
|
c
|
104
102
|
[2, 9] in ~/workspace/debug/target.rb
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
=>
|
111
|
-
|
112
|
-
|
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
|
113
111
|
=>#0 <module:Foo> at ~/workspace/debug/target.rb:7
|
114
112
|
#1 <main> at ~/workspace/debug/target.rb:1
|
115
113
|
|
116
114
|
Stop by #0 BP - Line /Users/naotto/workspace/debug/target.rb:7 (line)
|
117
115
|
INTERNAL_INFO: {"location":"~/workspace/debug/target.rb:7","line":7}
|
118
|
-
|
119
116
|
(rdbg)q!
|
120
117
|
q!
|
118
|
+
created: /Users/naotto/workspace/debug/test/tool/../debug/foo_test.rb
|
119
|
+
class: FooTest
|
120
|
+
method: test_1629720194
|
121
121
|
```
|
122
122
|
#### 4. The test file will be created as `test/debug/foo_test.rb`.
|
123
123
|
If the file already exists, **only method** will be added to it.
|
@@ -131,70 +131,70 @@ module DEBUGGER__
|
|
131
131
|
def program
|
132
132
|
<<~RUBY
|
133
133
|
1| module Foo
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
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
142
|
RUBY
|
143
143
|
end
|
144
144
|
|
145
|
-
def
|
145
|
+
def test_1629720194
|
146
146
|
debug_code(program) do
|
147
147
|
type 's'
|
148
148
|
assert_line_num 2
|
149
149
|
assert_line_text([
|
150
|
-
|
151
|
-
/
|
152
|
-
/=>
|
153
|
-
/
|
154
|
-
/
|
155
|
-
/
|
156
|
-
/
|
157
|
-
/
|
158
|
-
/
|
159
|
-
/
|
160
|
-
|
161
|
-
/
|
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
162
|
])
|
163
163
|
type 'n'
|
164
164
|
assert_line_num 3
|
165
165
|
assert_line_text([
|
166
|
-
|
167
|
-
/
|
168
|
-
/
|
169
|
-
/=>
|
170
|
-
/
|
171
|
-
/
|
172
|
-
/
|
173
|
-
/
|
174
|
-
/
|
175
|
-
/
|
176
|
-
|
177
|
-
/
|
178
|
-
/
|
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
179
|
])
|
180
180
|
type 'b 7'
|
181
|
-
assert_line_text(
|
181
|
+
assert_line_text(/\#0 BP \- Line .*/)
|
182
182
|
type 'c'
|
183
183
|
assert_line_num 7
|
184
184
|
assert_line_text([
|
185
|
-
|
186
|
-
/
|
187
|
-
/
|
188
|
-
/
|
189
|
-
/
|
190
|
-
/
|
191
|
-
/=>
|
192
|
-
/
|
193
|
-
/
|
194
|
-
|
195
|
-
/
|
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
196
|
//,
|
197
|
-
/Stop by
|
197
|
+
/Stop by \#0 BP \- Line .*/
|
198
198
|
])
|
199
199
|
type 'q!'
|
200
200
|
end
|
@@ -287,6 +287,7 @@ $ exe/rdbg -e 'b 20;; c ;; bt ;; info ;; q!' -e c target.rb
|
|
287
287
|
|
288
288
|
```
|
289
289
|
❯ exe/rdbg -e 'b 20;; c ;; bt ;; info ;; q!' -e c target.rb
|
290
|
+
DEBUGGER: Session start (pid: 9815)
|
290
291
|
[1, 10] in target.rb
|
291
292
|
=> 1| class Foo
|
292
293
|
2| def first_call
|
@@ -299,10 +300,10 @@ $ exe/rdbg -e 'b 20;; c ;; bt ;; info ;; q!' -e c target.rb
|
|
299
300
|
9| end
|
300
301
|
10| end
|
301
302
|
=>#0 <main> at target.rb:1
|
302
|
-
(rdbg:
|
303
|
-
#
|
304
|
-
(rdbg:
|
305
|
-
[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
|
306
307
|
15| yield(10)
|
307
308
|
16| end
|
308
309
|
17|
|
@@ -312,25 +313,26 @@ $ exe/rdbg -e 'b 20;; c ;; bt ;; info ;; q!' -e c target.rb
|
|
312
313
|
21| end
|
313
314
|
22|
|
314
315
|
23| Foo.new.first_call
|
316
|
+
24|
|
315
317
|
=>#0 Foo#forth_call(num1=20, num2=10) at target.rb:20 #=> 30
|
316
|
-
#1 block{|ten=10|} in second_call at target.rb:8
|
318
|
+
#1 block {|ten=10|} in second_call at target.rb:8
|
317
319
|
# and 4 frames (use `bt' command for all frames)
|
318
320
|
|
319
|
-
Stop by #
|
320
|
-
(rdbg:
|
321
|
+
Stop by #0 BP - Line /PATH_TO_PROJECT/target.rb:20 (return)
|
322
|
+
(rdbg:commands) bt
|
321
323
|
=>#0 Foo#forth_call(num1=20, num2=10) at target.rb:20 #=> 30
|
322
|
-
#1 block{|ten=10|} in second_call at target.rb:8
|
323
|
-
#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
|
324
326
|
#3 Foo#second_call(num=20) at target.rb:7
|
325
|
-
#4 first_call at target.rb:3
|
327
|
+
#4 Foo#first_call at target.rb:3
|
326
328
|
#5 <main> at target.rb:23
|
327
|
-
(rdbg:
|
329
|
+
(rdbg:commands) info
|
328
330
|
=>#0 Foo#forth_call(num1=20, num2=10) at target.rb:20 #=> 30
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
(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!
|
336
338
|
```
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -12,7 +12,7 @@ New debug.rb has several advantages:
|
|
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))
|
15
|
-
* Extensible: application can introduce debugging support with several
|
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,304 +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
|
-
If you use Bundler, write the following line to your Gemfile.
|
33
|
-
|
34
|
-
```
|
35
|
-
gem "debug", ">= 1.0.0.
|
36
|
-
```
|
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
|
37
148
|
|
38
|
-
|
39
|
-
$ rdbg -c bundle exec ruby target.rb
|
149
|
+
(rdbg)
|
40
150
|
```
|
41
151
|
|
42
|
-
|
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).
|
43
153
|
|
44
|
-
|
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)
|
45
157
|
|
46
|
-
|
158
|
+
(rdbg) b 5 # set breakpoint at line 5
|
159
|
+
#1 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:5 (line)
|
47
160
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
(b-1) is useful when you want to use debugging features after running the program.
|
54
|
-
(b-2) is also useful when you don't have a ssh access for the Ruby process.
|
55
|
-
|
56
|
-
To use debugging feature, you can have 3 ways.
|
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
|
+
```
|
57
165
|
|
58
|
-
|
59
|
-
* (2) Use `ruby -r debug...` command line option
|
60
|
-
* (3) Write `require 'debug...'` in .rb files
|
166
|
+
You can see that two breakpoints are registered. Let's continue the program by `continue` command.
|
61
167
|
|
62
|
-
|
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
|
63
179
|
|
64
|
-
|
180
|
+
Stop by #0 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:3 (line)
|
65
181
|
|
66
|
-
|
67
|
-
$ rdbg target.rb
|
68
|
-
$ rdbg -- -r foo -e expr # -- is required to make clear rdbg options and ruby's options
|
182
|
+
(rdbg)
|
69
183
|
```
|
70
184
|
|
71
|
-
|
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.
|
72
188
|
|
73
|
-
```
|
74
|
-
|
75
|
-
|
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
|
76
197
|
|
77
|
-
|
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
|
78
208
|
|
79
|
-
|
80
|
-
# target.rb
|
81
|
-
require 'debug/run' # start the debug console
|
209
|
+
Stop by #1 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:5 (line)
|
82
210
|
|
83
|
-
|
84
|
-
|
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
|
85
218
|
|
219
|
+
(rdbg) continue
|
220
|
+
[1, 2, 3, 4]
|
86
221
|
```
|
87
|
-
$ ruby target.rb
|
88
|
-
```
|
89
|
-
|
90
|
-
When you run the program with the debug console, you will see the debug console prompt `(rdbg)`.
|
91
|
-
The debuggee program (`target.rb`) is suspended at the beginning of `target.rb`.
|
92
|
-
|
93
|
-
You can type any debugger's command described bellow. "c" or "continue" resume the debuggee program.
|
94
|
-
You can suspend the debuggee program and show the debug console with `Ctrl-C`.
|
95
222
|
|
96
|
-
|
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.
|
97
225
|
|
98
|
-
|
99
|
-
$ rdbg ~/src/rb/target.rb
|
226
|
+
### Use `rdbg` with commands written in Ruby
|
100
227
|
|
101
|
-
|
102
|
-
=> 1| a = 1
|
103
|
-
2| b = 2
|
104
|
-
3| c = 3
|
105
|
-
4| p [a + b + c]
|
106
|
-
5|
|
107
|
-
--> #0 /home/ko1/src/rb/target.rb:1:in `<main>'
|
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.
|
108
229
|
|
109
|
-
|
110
|
-
|
111
|
-
a => nil
|
112
|
-
b => nil
|
113
|
-
c => nil
|
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.
|
114
232
|
|
115
|
-
|
116
|
-
|
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`
|
117
238
|
|
118
|
-
|
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`.
|
119
240
|
|
120
|
-
|
121
|
-
1| a = 1
|
122
|
-
=> 2| b = 2
|
123
|
-
3| c = 3
|
124
|
-
4| p [a + b + c]
|
125
|
-
5|
|
126
|
-
--> #0 /home/ko1/src/rb/target.rb:2:in `<main>'
|
241
|
+
NOTE: If you want to use bundler (`bundle` command), you need to write `gem debug` line in your `Gemfile`.
|
127
242
|
|
128
|
-
|
243
|
+
### Using VSCode
|
129
244
|
|
130
|
-
|
131
|
-
1| a = 1
|
132
|
-
2| b = 2
|
133
|
-
=> 3| c = 3
|
134
|
-
4| p [a + b + c]
|
135
|
-
5|
|
136
|
-
--> #0 /home/ko1/src/rb/target.rb:3:in `<main>'
|
245
|
+
Like other languages, you can use this debugger on the VSCode.
|
137
246
|
|
138
|
-
|
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.
|
139
253
|
|
140
|
-
[
|
141
|
-
1| a = 1
|
142
|
-
2| b = 2
|
143
|
-
3| c = 3
|
144
|
-
=> 4| p [a + b + c]
|
145
|
-
5|
|
146
|
-
--> #0 /home/ko1/src/rb/target.rb:4:in `<main>'
|
147
|
-
|
148
|
-
(rdbg) info # Show all local variables
|
149
|
-
%self => main
|
150
|
-
a => 1
|
151
|
-
b => 2
|
152
|
-
c => 3
|
153
|
-
|
154
|
-
(rdbg) c # Continue the program ("c" is a short name of "continue")
|
155
|
-
[6]
|
156
|
-
```
|
254
|
+
Please refer [Debugging in Visual Studio Code](https://code.visualstudio.com/docs/editor/debugging) for operations on VSCode.
|
157
255
|
|
158
|
-
|
256
|
+
You can configure the extension in `.vscode/launch.json`.
|
257
|
+
Please see the extension page for more details.
|
159
258
|
|
160
|
-
|
259
|
+
## Remote debugging
|
161
260
|
|
162
|
-
|
163
|
-
$ rdbg --open target.rb # or rdbg -O target.rb for shorthand
|
164
|
-
Debugger can attach via UNIX domain socket (/home/ko1/.ruby-debug-sock/ruby-debug-ko1-5042)
|
165
|
-
```
|
261
|
+
You can use this debugger as a remote debugger. For example, it will help the following situations:
|
166
262
|
|
167
|
-
|
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).
|
168
268
|
|
169
|
-
|
170
|
-
$ ruby -r debug/open target.rb
|
171
|
-
Debugger can attach via UNIX domain socket (/home/ko1/.ruby-debug-sock/ruby-debug-ko1-5042)
|
172
|
-
```
|
269
|
+
You can run your application as a remote debuggee and the remote debugger console can attach to the debuggee anytime.
|
173
270
|
|
174
|
-
|
271
|
+
### Invoke as a remote debuggee
|
175
272
|
|
176
|
-
|
177
|
-
# target.rb
|
178
|
-
require 'debug/open' # open the debugger entry point by UNIX domain socket.
|
273
|
+
There are two ways to invoke a script as remote debuggee: Use `rdbg --open` and require `debug/open` (or `debug/open_nonstop`).
|
179
274
|
|
180
|
-
|
275
|
+
#### `rdbg --open` (or `rdbg -O` for short)
|
181
276
|
|
182
|
-
|
183
|
-
DEBUGGER__.open # open the debugger entry point by UNIX domain socket.
|
184
|
-
# or DEBUGGER__.open_unix to specify UNIX domain socket.
|
185
|
-
```
|
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`.
|
186
278
|
|
187
|
-
```
|
188
|
-
$
|
189
|
-
|
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...
|
190
284
|
```
|
191
285
|
|
192
|
-
|
193
|
-
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).
|
194
287
|
|
195
|
-
|
196
|
-
$ rdbg -O ~/src/rb/target.rb
|
197
|
-
DEBUGGER: Debugger can attach via UNIX domain socket (/home/ko1/.ruby-debug-sock/ruby-debug-ko1-29828)
|
198
|
-
DEBUGGER: wait for debugger connection...
|
199
|
-
```
|
288
|
+
You can connect to the debuggee with `rdbg --attach` command (`rdbg -A` for short).
|
200
289
|
|
201
|
-
|
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
|
202
301
|
|
203
|
-
|
204
|
-
$ rdbg --attach # or rdbg -A for shorthand
|
205
|
-
|
206
|
-
[1, 4] in /home/ko1/src/rb/target.rb
|
207
|
-
1| (1..).each do |i|
|
208
|
-
=> 2| sleep 0.5
|
209
|
-
3| p i
|
210
|
-
4| end
|
211
|
-
--> #0 [C] /home/ko1/src/rb/target.rb:2:in `sleep'
|
212
|
-
#1 /home/ko1/src/rb/target.rb:2:in `block in <main>' {|i=17|}
|
213
|
-
#2 [C] /home/ko1/src/rb/target.rb:1:in `each'
|
214
|
-
# and 1 frames (use `bt' command for all frames)
|
215
|
-
|
216
|
-
(rdb)
|
302
|
+
(rdbg:remote)
|
217
303
|
```
|
218
304
|
|
219
|
-
|
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.
|
220
306
|
|
221
|
-
|
222
|
-
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.
|
223
308
|
|
224
|
-
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.
|
225
310
|
|
226
|
-
|
227
|
-
* 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`.
|
228
312
|
|
229
|
-
|
313
|
+
To connect to the debuggee, you need to specify the port.
|
230
314
|
|
231
|
-
```
|
232
|
-
$ rdbg --attach
|
233
|
-
Please select a debug session:
|
234
|
-
ruby-debug-ko1-19638
|
235
|
-
ruby-debug-ko1-19603
|
315
|
+
```shell
|
316
|
+
$ rdbg --attach 12345
|
236
317
|
```
|
237
318
|
|
238
|
-
|
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.
|
239
321
|
|
240
|
-
|
241
|
-
$ rdbg --attach ruby-debug-ko1-19638
|
242
|
-
```
|
322
|
+
#### `require 'debug/open'` in a program
|
243
323
|
|
244
|
-
|
245
|
-
* `RUBY_DEBUG_SOCK_DIR` environment variable if available.
|
246
|
-
* `XDG_RUNTIME_DIR` environment variable if available.
|
247
|
-
* `$HOME/.ruby-debug-sock` if `$HOME` is available.
|
324
|
+
If you can modify the program, you can open debugging port by adding `require 'debug/open'` line in the program.
|
248
325
|
|
249
|
-
|
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.
|
250
330
|
|
251
|
-
|
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.
|
252
332
|
|
253
|
-
|
254
|
-
|
255
|
-
```
|
256
|
-
$ rdbg -O --port=12345 target.rb
|
257
|
-
# or
|
258
|
-
$ rdbg --open --port=12345 target.rb
|
259
|
-
Debugger can attach via TCP/IP (localhost:12345)
|
333
|
+
```shell
|
334
|
+
$ RUBY_DEBUG_PORT=12345 ruby target.rb
|
260
335
|
```
|
261
336
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
```
|
266
|
-
$ RUBY_DEBUG_PORT=12345 ruby -r debug/open target.rb
|
267
|
-
Debugger can attach via TCP/IP (localhost:12345)
|
268
|
-
```
|
337
|
+
## Configuration
|
269
338
|
|
270
|
-
|
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.
|
271
341
|
|
272
|
-
|
273
|
-
# target.rb
|
274
|
-
require 'debug/open' # open the debugger entry point.
|
275
|
-
```
|
342
|
+
### Configuration list
|
276
343
|
|
277
|
-
|
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.
|
278
345
|
|
279
346
|
```
|
280
|
-
|
281
|
-
|
347
|
+
# configuration example
|
348
|
+
config set log_level INFO
|
349
|
+
config set no_color true
|
282
350
|
```
|
283
351
|
|
284
|
-
or
|
285
352
|
|
286
|
-
```ruby
|
287
|
-
# target.rb
|
288
|
-
require 'debug/server' # introduce remote debugging feature
|
289
|
-
DEBUGGER__.open(port: 12345)
|
290
|
-
# or DEBUGGER__.open_tcp(port: 12345)
|
291
|
-
```
|
292
353
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
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)
|
297
362
|
|
298
|
-
|
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)
|
299
370
|
|
300
|
-
|
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)
|
301
376
|
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
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
|
306
383
|
|
307
384
|
### Initial scripts
|
308
385
|
|
309
|
-
If there
|
310
|
-
|
311
|
-
If there are `~/.rdbgrc.rb` is available, it is loaded as a ruby script at same timing.
|
386
|
+
If there is `~/.rdbgrc`, the file is loaded as an initial script (which contains debug commands) when the debug session is started.
|
312
387
|
|
313
|
-
|
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).
|
314
390
|
|
315
|
-
|
391
|
+
Initial scripts are useful to write your favorite configurations.
|
392
|
+
For example, you can set break points with `break file:123` in `~/.rdbgrc`.
|
316
393
|
|
317
|
-
|
318
|
-
* `RUBY_DEBUG_INIT_SCRIPT`: Initial script path loaded at the first stop.
|
319
|
-
* `RUBY_DEBUG_COMMANDS`: Debug commands invoked at the first stop. Commands should be separated by ';;'.
|
320
|
-
* `RUBY_DEBUG_SHOW_SRC_LINES`: Show n lines source code on breakpoint (default: 10 lines).
|
321
|
-
* `RUBY_DEBUG_SHOW_FRAMES`: Show n frames on breakpoint (default: 2 frames).
|
322
|
-
* Remote debugging
|
323
|
-
* `RUBY_DEBUG_PORT`: TCP/IP remote debugging: port to open.
|
324
|
-
* `RUBY_DEBUG_HOST`: TCP/IP remote debugging: host (localhost if not given) to open.
|
325
|
-
* `RUBY_DEBUG_SOCK_PATH`: UNIX Domain Socket remote debugging: socket path to open.
|
326
|
-
* `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.
|
327
395
|
|
328
396
|
## Debug command on the debug console
|
329
397
|
|
398
|
+
On the debug console, you can use the following debug commands.
|
399
|
+
|
330
400
|
* `Enter` repeats the last command (useful when repeating `step`s).
|
331
401
|
* `Ctrl-D` is equal to `quit` command.
|
332
402
|
* [debug command compare sheet - Google Sheets](https://docs.google.com/spreadsheets/d/1TlmmUDsvwK4sSIyoMv-io52BUUz__R5wpu-ComXlsw0/edit?usp=sharing)
|
@@ -339,10 +409,16 @@ The `<...>` notation means the argument.
|
|
339
409
|
|
340
410
|
* `s[tep]`
|
341
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.
|
342
414
|
* `n[ext]`
|
343
415
|
* Step over. Resume the program until next line.
|
416
|
+
* `n[ext] <n>`
|
417
|
+
* Step over, same as `step <n>`.
|
344
418
|
* `fin[ish]`
|
345
419
|
* Finish this frame. Resume the program until the current frame is finished.
|
420
|
+
* `fin[ish] <n>`
|
421
|
+
* Finish frames, same as `step <n>`.
|
346
422
|
* `c[ontinue]`
|
347
423
|
* Resume the program.
|
348
424
|
* `q[uit]` or `Ctrl-D`
|
@@ -366,10 +442,14 @@ The `<...>` notation means the argument.
|
|
366
442
|
* Set breakpoint on the method `<class>#<name>`.
|
367
443
|
* `b[reak] <expr>.<name>`
|
368
444
|
* Set breakpoint on the method `<expr>.<name>`.
|
369
|
-
* `b[reak] ... if <expr>`
|
445
|
+
* `b[reak] ... if: <expr>`
|
370
446
|
* break if `<expr>` is true at specified location.
|
371
|
-
* `b[reak]
|
372
|
-
* 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.
|
373
453
|
* Note that this feature is super slow.
|
374
454
|
* `catch <Error>`
|
375
455
|
* Set breakpoint on raising `<Error>`.
|
@@ -385,6 +465,12 @@ The `<...>` notation means the argument.
|
|
385
465
|
|
386
466
|
* `bt` or `backtrace`
|
387
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/`.
|
388
474
|
* `l[ist]`
|
389
475
|
* Show current frame's source code.
|
390
476
|
* Next `list` command shows the successor lines.
|
@@ -397,11 +483,26 @@ The `<...>` notation means the argument.
|
|
397
483
|
* Note that edited file will not be reloaded.
|
398
484
|
* `edit <file>`
|
399
485
|
* Open <file> on the editor.
|
400
|
-
* `i[nfo]
|
486
|
+
* `i[nfo]`
|
487
|
+
* Show information about current frame (local/instance variables and defined constants).
|
488
|
+
* `i[nfo] l[ocal[s]]`
|
401
489
|
* Show information about the current frame (local variables)
|
402
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/>`.
|
403
499
|
* `i[nfo] th[read[s]]`
|
404
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.
|
405
506
|
* `display`
|
406
507
|
* Show display setting.
|
407
508
|
* `display <expr>`
|
@@ -410,8 +511,6 @@ The `<...>` notation means the argument.
|
|
410
511
|
* Remove all display settings.
|
411
512
|
* `undisplay <displaynum>`
|
412
513
|
* Remove a specified display setting.
|
413
|
-
* `trace [on|off]`
|
414
|
-
* enable or disable line tracer.
|
415
514
|
|
416
515
|
### Frame control
|
417
516
|
|
@@ -435,6 +534,36 @@ The `<...>` notation means the argument.
|
|
435
534
|
* `irb`
|
436
535
|
* Invoke `irb` on the current frame.
|
437
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
|
+
|
438
567
|
### Thread control
|
439
568
|
|
440
569
|
* `th[read]`
|
@@ -442,6 +571,21 @@ The `<...>` notation means the argument.
|
|
442
571
|
* `th[read] <thnum>`
|
443
572
|
* Switch thread specified by `<thnum>`.
|
444
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
|
+
|
445
589
|
### Help
|
446
590
|
|
447
591
|
* `h[elp]`
|
@@ -450,6 +594,83 @@ The `<...>` notation means the argument.
|
|
450
594
|
* Show help for the given command.
|
451
595
|
|
452
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
|
+
|
453
674
|
## rdbg command help
|
454
675
|
|
455
676
|
```
|
@@ -457,10 +678,11 @@ exe/rdbg [options] -- [debuggee options]
|
|
457
678
|
|
458
679
|
Debug console mode:
|
459
680
|
-n, --nonstop Do not stop at the beginning of the script.
|
460
|
-
-e
|
681
|
+
-e DEBUG_COMMAND Execute debug command at the beginning of the script.
|
461
682
|
-x, --init-script=FILE Execute debug command in the FILE.
|
462
683
|
--no-rc Ignore ~/.rdbgrc
|
463
684
|
--no-color Disable colorize
|
685
|
+
--no-sigint-hook Disable to trap SIGINT
|
464
686
|
-c, --command Enable command mode.
|
465
687
|
The first argument should be a command name in $PATH.
|
466
688
|
Example: 'rdbg -c bundle exec rake test'
|
@@ -468,7 +690,7 @@ Debug console mode:
|
|
468
690
|
-O, --open Start remote debugging with opening the network port.
|
469
691
|
If TCP/IP options are not given,
|
470
692
|
a UNIX domain socket will be used.
|
471
|
-
--sock-path=SOCK_PATH UNIX
|
693
|
+
--sock-path=SOCK_PATH UNIX Domain socket path
|
472
694
|
--port=PORT Listening TCP/IP port
|
473
695
|
--host=HOST Listening TCP/IP host
|
474
696
|
--cookie=COOKIE Set a cookie for connection
|
@@ -477,6 +699,9 @@ Debug console mode:
|
|
477
699
|
|
478
700
|
'rdbg target.rb foo bar' starts like 'ruby target.rb foo bar'.
|
479
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'.
|
480
705
|
'rdbg -O target.rb foo bar' starts and accepts attaching with UNIX domain socket.
|
481
706
|
'rdbg -O --port 1234 target.rb foo bar' starts accepts attaching with TCP/IP localhost:1234.
|
482
707
|
'rdbg -O --port 1234 -- -r foo -e bar' starts accepts attaching with TCP/IP localhost:1234.
|
@@ -506,6 +731,7 @@ NOTE
|
|
506
731
|
# Contributing
|
507
732
|
|
508
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.
|
509
735
|
|
510
736
|
Please also check the [contributing guideline](/CONTRIBUTING.md).
|
511
737
|
|