debug 1.0.0.beta3 → 1.0.0.beta4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CONTRIBUTING.md +97 -0
- data/Gemfile +1 -1
- data/README.md +18 -14
- data/TODO.md +33 -0
- data/ext/debug/debug.c +1 -1
- data/lib/debug.rb +1 -1
- data/lib/debug/breakpoint.rb +6 -2
- data/lib/debug/config.rb +42 -13
- data/lib/debug/frame_info.rb +113 -0
- data/lib/debug/server.rb +11 -20
- data/lib/debug/session.rb +65 -34
- data/lib/debug/source_repository.rb +36 -6
- data/lib/debug/thread_client.rb +40 -113
- data/lib/debug/version.rb +1 -1
- data/misc/README.md.erb +5 -2
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebaae12c10e51036f850fd1cbcde66d891a1e50b64bc5d96bfdab610cb42fd1d
|
4
|
+
data.tar.gz: e62eee365aa1409c650049ccb8ed237854aeed6f7a066dc2b84f96c9cffefd12
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2aa2b044268220dc79d72850f6366474fff647fa6893360044ce64a8a97e4d759e414da6c39dac52a6b33593512675091ed4fb4a7399c1357b344d342f3c812f
|
7
|
+
data.tar.gz: 506d0afeb3e3926da6631e99234fd2ba4c96220d5def5a95d0e51afa54ae28beb19c30873c3c0cf9a95fa975023364f7088a0190d26452e307e715925e21a78c
|
data/.gitignore
CHANGED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
## Manually Test Your Changes
|
2
|
+
|
3
|
+
You can manually test your changes with a simple Ruby script + a line of command. The following example will help you check:
|
4
|
+
|
5
|
+
- Breakpoint insertion.
|
6
|
+
- Resume from the breakpoint.
|
7
|
+
- Backtrace display.
|
8
|
+
- Information (local variables, ivars..etc.) display.
|
9
|
+
- Debugger exit.
|
10
|
+
|
11
|
+
|
12
|
+
### Script
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
# target.rb
|
16
|
+
class Foo
|
17
|
+
def first_call
|
18
|
+
second_call(20)
|
19
|
+
end
|
20
|
+
|
21
|
+
def second_call(num)
|
22
|
+
third_call_with_block do |ten|
|
23
|
+
forth_call(num, ten)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def third_call_with_block(&block)
|
28
|
+
@ivar1 = 10; @ivar2 = 20
|
29
|
+
|
30
|
+
yield(10)
|
31
|
+
end
|
32
|
+
|
33
|
+
def forth_call(num1, num2)
|
34
|
+
num1 + num2
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
Foo.new.first_call
|
39
|
+
```
|
40
|
+
|
41
|
+
### Command
|
42
|
+
|
43
|
+
```
|
44
|
+
$ exe/rdbg -e 'b 20;; c ;; bt ;; info ;; q!' -e c target.rb
|
45
|
+
```
|
46
|
+
|
47
|
+
### Expect Result
|
48
|
+
|
49
|
+
```
|
50
|
+
❯ exe/rdbg -e 'b 20;; c ;; bt ;; info ;; q!' -e c target.rb
|
51
|
+
[1, 10] in target.rb
|
52
|
+
=> 1| class Foo
|
53
|
+
2| def first_call
|
54
|
+
3| second_call(20)
|
55
|
+
4| end
|
56
|
+
5|
|
57
|
+
6| def second_call(num)
|
58
|
+
7| third_call_with_block do |ten|
|
59
|
+
8| forth_call(num, ten)
|
60
|
+
9| end
|
61
|
+
10| end
|
62
|
+
=>#0 <main> at target.rb:1
|
63
|
+
(rdbg:init) b 20
|
64
|
+
#1 line bp /PATH_TO_PROJECT/debug/target.rb:20 (return)
|
65
|
+
(rdbg:init) c
|
66
|
+
[15, 23] in target.rb
|
67
|
+
15| yield(10)
|
68
|
+
16| end
|
69
|
+
17|
|
70
|
+
18| def forth_call(num1, num2)
|
71
|
+
19| num1 + num2
|
72
|
+
=> 20| end
|
73
|
+
21| end
|
74
|
+
22|
|
75
|
+
23| Foo.new.first_call
|
76
|
+
=>#0 Foo#forth_call(num1=20, num2=10) at target.rb:20 #=> 30
|
77
|
+
#1 block{|ten=10|} in second_call at target.rb:8
|
78
|
+
# and 4 frames (use `bt' command for all frames)
|
79
|
+
|
80
|
+
Stop by #1 line bp /PATH_TO_PROJECT/debug/target.rb:20 (return)
|
81
|
+
(rdbg:init) bt
|
82
|
+
=>#0 Foo#forth_call(num1=20, num2=10) at target.rb:20 #=> 30
|
83
|
+
#1 block{|ten=10|} in second_call at target.rb:8
|
84
|
+
#2 Foo#third_call_with_block(block=#<Proc:0x00007f8bc32f0c28 target.rb:7>) at target.rb:15
|
85
|
+
#3 Foo#second_call(num=20) at target.rb:7
|
86
|
+
#4 first_call at target.rb:3
|
87
|
+
#5 <main> at target.rb:23
|
88
|
+
(rdbg:init) info
|
89
|
+
=>#0 Foo#forth_call(num1=20, num2=10) at target.rb:20 #=> 30
|
90
|
+
%self => #<Foo:0x00007f8bc32f0ed0>
|
91
|
+
%return => 30
|
92
|
+
num1 => 20
|
93
|
+
num2 => 10
|
94
|
+
@ivar1 => 10
|
95
|
+
@ivar2 => 20
|
96
|
+
(rdbg:init) q!
|
97
|
+
```
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -62,13 +62,14 @@ $ ruby -r debug/run target.rb
|
|
62
62
|
|
63
63
|
$ cat target.rb
|
64
64
|
require 'debug/run' # start the debug console
|
65
|
-
...
|
65
|
+
... rest of program ...
|
66
66
|
|
67
67
|
# or
|
68
68
|
|
69
69
|
$ cat target.rb
|
70
70
|
require 'debug/session' # introduce the functionality
|
71
71
|
DEBUGGER__.console # and start the debug console
|
72
|
+
... rest of program ...
|
72
73
|
|
73
74
|
$ ruby target.rb
|
74
75
|
```
|
@@ -373,11 +374,11 @@ The `<...>` notation means the argument.
|
|
373
374
|
* Note that edited file will not be reloaded.
|
374
375
|
* `edit <file>`
|
375
376
|
* Open <file> on the editor.
|
376
|
-
* `i[nfo]`
|
377
|
+
* `i[nfo]`, `i[nfo] l[ocal[s]]`
|
377
378
|
* Show information about the current frame (local variables)
|
378
379
|
* It includes `self` as `%self` and a return value as `%return`.
|
379
|
-
* `i[nfo]
|
380
|
-
* Show
|
380
|
+
* `i[nfo] th[read[s]]
|
381
|
+
* Show all threads (same as `th[read]`).
|
381
382
|
* `display`
|
382
383
|
* Show display setting.
|
383
384
|
* `display <expr>`
|
@@ -437,27 +438,28 @@ Debug console mode:
|
|
437
438
|
-O, --open Start debuggee with opening the debugger port.
|
438
439
|
If TCP/IP options are not given,
|
439
440
|
a UNIX domain socket will be used.
|
441
|
+
--sock-path=[SOCK_PATH] UNIX Doman socket path
|
440
442
|
--port=[PORT] Listening TCP/IP port
|
441
443
|
--host=[HOST] Listening TCP/IP host
|
442
444
|
|
443
445
|
Debug console mode runs Ruby program with the debug console.
|
444
446
|
|
445
|
-
rdbg target.rb foo bar
|
446
|
-
rdbg -- -r foo -e bar
|
447
|
-
rdbg -O target.rb foo bar
|
448
|
-
rdbg -O --port 1234 target.rb foo bar
|
449
|
-
rdbg -O --port 1234 -- -r foo -e bar
|
447
|
+
'rdbg target.rb foo bar' starts like 'ruby target.rb foo bar'.
|
448
|
+
'rdbg -- -r foo -e bar' starts like 'ruby -r foo -e bar'.
|
449
|
+
'rdbg -O target.rb foo bar' starts and accepts attaching with UNIX domain socket.
|
450
|
+
'rdbg -O --port 1234 target.rb foo bar' starts accepts attaching with TCP/IP localhost:1234.
|
451
|
+
'rdbg -O --port 1234 -- -r foo -e bar' starts accepts attaching with TCP/IP localhost:1234.
|
450
452
|
|
451
453
|
Attach mode:
|
452
454
|
-A, --attach Attach to debuggee process.
|
453
455
|
|
454
456
|
Attach mode attaches the remote debug console to the debuggee process.
|
455
457
|
|
456
|
-
'rdbg -A'
|
457
|
-
|
458
|
-
|
459
|
-
'rdbg -A path'
|
460
|
-
'rdbg -A port'
|
458
|
+
'rdbg -A' tries to connect via UNIX domain socket.
|
459
|
+
If there are multiple processes are waiting for the
|
460
|
+
debugger connection, list possible debuggee names.
|
461
|
+
'rdbg -A path' tries to connect via UNIX domain socket with given path name.
|
462
|
+
'rdbg -A port' tries to connect to localhost:port via TCP/IP.
|
461
463
|
'rdbg -A host port' tries to connect to host:port via TCP/IP.
|
462
464
|
|
463
465
|
```
|
@@ -465,3 +467,5 @@ Attach mode:
|
|
465
467
|
# Contributing
|
466
468
|
|
467
469
|
Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/debug.
|
470
|
+
|
471
|
+
Please also check the [contributing guideline](/CONTRIBUTING.md).
|
data/TODO.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# TODO
|
2
|
+
|
3
|
+
## Basic functionality
|
4
|
+
|
5
|
+
* VScode DAP support
|
6
|
+
* Support Ractors
|
7
|
+
* Signal (SIGINT) support
|
8
|
+
* Remote connection with openssl
|
9
|
+
|
10
|
+
## UI
|
11
|
+
|
12
|
+
* Coloring
|
13
|
+
* Interactive breakpoint setting
|
14
|
+
* irb integration
|
15
|
+
* Web browser integrated UI
|
16
|
+
|
17
|
+
## Debug command
|
18
|
+
|
19
|
+
* Breakpoints
|
20
|
+
* Lightweight pending method break points with Ruby 3.1 feature (TP:method_added)
|
21
|
+
* Non-stop breakpoint but runs some code.
|
22
|
+
* Watch points
|
23
|
+
* Lightweight watchpoints for instance variables with Ruby 3.1 features (TP:ivar_set)
|
24
|
+
* Faster `next`/`finish` command by specifying target code.
|
25
|
+
* `set`/`show` configurations
|
26
|
+
* In-memory line traces
|
27
|
+
* Timemachine debugging
|
28
|
+
|
29
|
+
## Tests
|
30
|
+
|
31
|
+
* Test framework
|
32
|
+
* Tests for commands
|
33
|
+
* Tests for remote debugging
|
data/ext/debug/debug.c
CHANGED
@@ -90,7 +90,7 @@ method_added_tracker(VALUE tpval, void *ptr)
|
|
90
90
|
VALUE mid = rb_tracearg_callee_id(arg);
|
91
91
|
|
92
92
|
if (RB_UNLIKELY(mid == ID2SYM(rb_intern("method_added")) ||
|
93
|
-
mid == ID2SYM(rb_intern("
|
93
|
+
mid == ID2SYM(rb_intern("singleton_method_added")))) {
|
94
94
|
VALUE args[] = {
|
95
95
|
tpval,
|
96
96
|
};
|
data/lib/debug.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require_relative 'debug/
|
1
|
+
require_relative 'debug/session'
|
data/lib/debug/breakpoint.rb
CHANGED
@@ -209,7 +209,7 @@ module DEBUGGER__
|
|
209
209
|
@tp = TracePoint.new(:raise){|tp|
|
210
210
|
exc = tp.raised_exception
|
211
211
|
exc.class.ancestors.each{|cls|
|
212
|
-
suspend if pat === cls.name
|
212
|
+
suspend if @pat === cls.name
|
213
213
|
}
|
214
214
|
}
|
215
215
|
end
|
@@ -333,7 +333,11 @@ module DEBUGGER__
|
|
333
333
|
end
|
334
334
|
end
|
335
335
|
|
336
|
-
def enable
|
336
|
+
def enable
|
337
|
+
try_enable
|
338
|
+
end
|
339
|
+
|
340
|
+
def try_enable quiet: false
|
337
341
|
eval_class_name
|
338
342
|
search_method
|
339
343
|
|
data/lib/debug/config.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
module DEBUGGER__
|
3
3
|
def self.unix_domain_socket_dir
|
4
4
|
case
|
5
|
-
when path = DEBUGGER__::CONFIG[:sock_dir]
|
5
|
+
when path = ::DEBUGGER__::CONFIG[:sock_dir]
|
6
6
|
when path = ENV['XDG_RUNTIME_DIR']
|
7
7
|
when home = ENV['HOME']
|
8
8
|
path = File.join(home, '.ruby-debug-sock')
|
@@ -40,25 +40,39 @@ module DEBUGGER__
|
|
40
40
|
show_frames: 'RUBY_DEBUG_SHOW_FRAMES', # Show n frames on breakpoint (default: 2 frames).
|
41
41
|
use_short_path: 'RUBY_DEBUG_USE_SHORT_PATH', # Show shoten PATH (like $(Gem)/foo.rb).
|
42
42
|
skip_nosrc: 'RUBY_DEBUG_SKIP_NOSRC', # Skip on no source code lines (default: false).
|
43
|
+
use_colorize: 'RUBY_DEBUG_USE_COLORIZE', # Show coloring
|
43
44
|
|
44
45
|
# remote
|
45
46
|
port: 'RUBY_DEBUG_PORT', # TCP/IP remote debugging: port
|
46
47
|
host: 'RUBY_DEBUG_HOST', # TCP/IP remote debugging: host (localhost if not given)
|
48
|
+
sock_path: 'RUBY_DEBUG_SOCK_PATH', # UNIX Domain Socket remote debugging: socket path
|
47
49
|
sock_dir: 'RUBY_DEBUG_SOCK_DIR', # UNIX Domain Socket remote debugging: socket directory
|
48
50
|
}.freeze
|
49
51
|
|
50
52
|
def self.config_to_env config
|
51
53
|
CONFIG_MAP.each{|key, evname|
|
52
|
-
ENV[evname] = config[key]
|
54
|
+
ENV[evname] = config[key].to_s if config[key]
|
53
55
|
}
|
54
56
|
end
|
55
57
|
|
56
58
|
def self.parse_argv argv
|
57
59
|
config = {
|
58
60
|
mode: :start,
|
61
|
+
use_colorize: true,
|
59
62
|
}
|
60
63
|
CONFIG_MAP.each{|key, evname|
|
61
|
-
|
64
|
+
if val = ENV[evname]
|
65
|
+
if /_USE_/ =~ evname || /NONSTOP/ =~ evname
|
66
|
+
case val
|
67
|
+
when '1', 'true', 'TRUE', 'T'
|
68
|
+
config[key] = true
|
69
|
+
else
|
70
|
+
config[key] = false
|
71
|
+
end
|
72
|
+
else
|
73
|
+
config[key] = val
|
74
|
+
end
|
75
|
+
end
|
62
76
|
}
|
63
77
|
return config if !argv || argv.empty?
|
64
78
|
|
@@ -83,6 +97,9 @@ module DEBUGGER__
|
|
83
97
|
'a UNIX domain socket will be used.') do
|
84
98
|
config[:remote] = true
|
85
99
|
end
|
100
|
+
o.on('--sock-path=[SOCK_PATH]', 'UNIX Doman socket path') do |path|
|
101
|
+
config[:sock_path] = path
|
102
|
+
end
|
86
103
|
o.on('--port=[PORT]', 'Listening TCP/IP port') do |port|
|
87
104
|
config[:port] = port
|
88
105
|
end
|
@@ -95,11 +112,11 @@ module DEBUGGER__
|
|
95
112
|
o.separator ''
|
96
113
|
o.separator ' Debug console mode runs Ruby program with the debug console.'
|
97
114
|
o.separator ''
|
98
|
-
o.separator " #{rdbg} target.rb foo bar
|
99
|
-
o.separator " #{rdbg} -- -r foo -e bar
|
100
|
-
o.separator " #{rdbg} -O target.rb foo bar
|
101
|
-
o.separator " #{rdbg} -O --port 1234 target.rb foo bar
|
102
|
-
o.separator " #{rdbg} -O --port 1234 -- -r foo -e bar
|
115
|
+
o.separator " '#{rdbg} target.rb foo bar' starts like 'ruby target.rb foo bar'."
|
116
|
+
o.separator " '#{rdbg} -- -r foo -e bar' starts like 'ruby -r foo -e bar'."
|
117
|
+
o.separator " '#{rdbg} -O target.rb foo bar' starts and accepts attaching with UNIX domain socket."
|
118
|
+
o.separator " '#{rdbg} -O --port 1234 target.rb foo bar' starts accepts attaching with TCP/IP localhost:1234."
|
119
|
+
o.separator " '#{rdbg} -O --port 1234 -- -r foo -e bar' starts accepts attaching with TCP/IP localhost:1234."
|
103
120
|
|
104
121
|
o.separator ''
|
105
122
|
o.separator 'Attach mode:'
|
@@ -110,11 +127,11 @@ module DEBUGGER__
|
|
110
127
|
o.separator ''
|
111
128
|
o.separator ' Attach mode attaches the remote debug console to the debuggee process.'
|
112
129
|
o.separator ''
|
113
|
-
o.separator " '#{rdbg} -A'
|
114
|
-
o.separator " #{' ' * rdbg.size}
|
115
|
-
o.separator " #{' ' * rdbg.size}
|
116
|
-
o.separator " '#{rdbg} -A path'
|
117
|
-
o.separator " '#{rdbg} -A port'
|
130
|
+
o.separator " '#{rdbg} -A' tries to connect via UNIX domain socket."
|
131
|
+
o.separator " #{' ' * rdbg.size} If there are multiple processes are waiting for the"
|
132
|
+
o.separator " #{' ' * rdbg.size} debugger connection, list possible debuggee names."
|
133
|
+
o.separator " '#{rdbg} -A path' tries to connect via UNIX domain socket with given path name."
|
134
|
+
o.separator " '#{rdbg} -A port' tries to connect to localhost:port via TCP/IP."
|
118
135
|
o.separator " '#{rdbg} -A host port' tries to connect to host:port via TCP/IP."
|
119
136
|
end
|
120
137
|
|
@@ -122,4 +139,16 @@ module DEBUGGER__
|
|
122
139
|
|
123
140
|
config
|
124
141
|
end
|
142
|
+
|
143
|
+
CONFIG = ::DEBUGGER__.parse_argv(ENV['RUBY_DEBUG_OPT'])
|
144
|
+
|
145
|
+
def self.set_config kw
|
146
|
+
kw.each{|k, v|
|
147
|
+
if CONFIG_MAP[k]
|
148
|
+
CONFIG[k] = v # TODO: ractor support
|
149
|
+
else
|
150
|
+
raise "unknown option: #{k}"
|
151
|
+
end
|
152
|
+
}
|
153
|
+
end
|
125
154
|
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
|
2
|
+
module DEBUGGER__
|
3
|
+
FrameInfo = Struct.new(:location, :self, :binding, :iseq, :class, :frame_depth,
|
4
|
+
:has_return_value, :return_value, :show_line)
|
5
|
+
|
6
|
+
|
7
|
+
# extend FrameInfo with debug.so
|
8
|
+
if File.exist? File.join(__dir__, 'debug.so')
|
9
|
+
require_relative 'debug.so'
|
10
|
+
else
|
11
|
+
require "debug/debug"
|
12
|
+
end
|
13
|
+
|
14
|
+
class FrameInfo
|
15
|
+
HOME = ENV['HOME'] ? (ENV['HOME'] + '/') : nil
|
16
|
+
|
17
|
+
def path
|
18
|
+
location.path
|
19
|
+
end
|
20
|
+
|
21
|
+
def realpath
|
22
|
+
location.absolute_path
|
23
|
+
end
|
24
|
+
|
25
|
+
def pretty_path
|
26
|
+
use_short_path = ::DEBUGGER__::CONFIG[:use_short_path]
|
27
|
+
|
28
|
+
case
|
29
|
+
when use_short_path && path.start_with?(dir = ::DEBUGGER__::CONFIG["rubylibdir"] + '/')
|
30
|
+
path.sub(dir, '$(rubylibdir)/')
|
31
|
+
when use_short_path && Gem.path.any? do |gp|
|
32
|
+
path.start_with?(dir = gp + '/gems/')
|
33
|
+
end
|
34
|
+
path.sub(dir, '$(Gem)/')
|
35
|
+
when HOME && path.start_with?(HOME)
|
36
|
+
path.sub(HOME, '~/')
|
37
|
+
else
|
38
|
+
path
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def file_lines
|
43
|
+
SESSION.source(realpath || path)
|
44
|
+
end
|
45
|
+
|
46
|
+
def call_identifier_str
|
47
|
+
if binding && iseq
|
48
|
+
if iseq.type == :block
|
49
|
+
if (argc = iseq.argc) > 0
|
50
|
+
args = parameters_info iseq.locals[0...argc]
|
51
|
+
args_str = "{|#{args}|}"
|
52
|
+
end
|
53
|
+
|
54
|
+
location.label.sub('block'){ "block#{args_str}" }
|
55
|
+
elsif (callee = binding.eval('__callee__', __FILE__, __LINE__)) && (argc = iseq.argc) > 0
|
56
|
+
args = parameters_info iseq.locals[0...argc]
|
57
|
+
"#{klass_sig}#{callee}(#{args})"
|
58
|
+
else
|
59
|
+
location.label
|
60
|
+
end
|
61
|
+
else
|
62
|
+
"[C] #{klass_sig}#{location.base_label}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def return_str
|
67
|
+
if binding && iseq && has_return_value
|
68
|
+
short_inspect(return_value)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def location_str
|
73
|
+
"#{pretty_path}:#{location.lineno}"
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
SHORT_INSPECT_LENGTH = 40
|
79
|
+
|
80
|
+
def short_inspect obj
|
81
|
+
str = obj.inspect
|
82
|
+
if str.length > SHORT_INSPECT_LENGTH
|
83
|
+
str[0...SHORT_INSPECT_LENGTH] + '...'
|
84
|
+
else
|
85
|
+
str
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def get_singleton_class obj
|
90
|
+
obj.singleton_class # TODO: don't use it
|
91
|
+
rescue TypeError
|
92
|
+
nil
|
93
|
+
end
|
94
|
+
|
95
|
+
def parameters_info vars
|
96
|
+
vars.map{|var|
|
97
|
+
begin
|
98
|
+
"#{var}=#{short_inspect(binding.local_variable_get(var))}"
|
99
|
+
rescue NameError, TypeError
|
100
|
+
nil
|
101
|
+
end
|
102
|
+
}.compact.join(', ')
|
103
|
+
end
|
104
|
+
|
105
|
+
def klass_sig
|
106
|
+
if self.class == get_singleton_class(self.self)
|
107
|
+
"#{self.self}."
|
108
|
+
else
|
109
|
+
"#{self.class}#"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
data/lib/debug/server.rb
CHANGED
@@ -187,39 +187,30 @@ module DEBUGGER__
|
|
187
187
|
end
|
188
188
|
|
189
189
|
class UI_UnixDomainServer < UI_ServerBase
|
190
|
-
def initialize sock_dir: nil
|
190
|
+
def initialize sock_dir: nil, sock_path: nil
|
191
|
+
@sock_path = sock_path
|
191
192
|
@sock_dir = sock_dir || DEBUGGER__.unix_domain_socket_dir
|
192
193
|
|
193
194
|
super()
|
194
195
|
end
|
195
196
|
|
196
197
|
def accept
|
197
|
-
|
198
|
+
case
|
199
|
+
when @sock_path
|
200
|
+
when sp = ::DEBUGGER__::CONFIG[:sock_path]
|
201
|
+
@sock_path = sp
|
202
|
+
else
|
203
|
+
@sock_path = DEBUGGER__.create_unix_domain_socket_name(@sock_dir)
|
204
|
+
end
|
198
205
|
|
199
|
-
::DEBUGGER__.message "Debugger can attach via UNIX domain socket (#{@
|
200
|
-
Socket.unix_server_loop @
|
206
|
+
::DEBUGGER__.message "Debugger can attach via UNIX domain socket (#{@sock_path})"
|
207
|
+
Socket.unix_server_loop @sock_path do |sock, client|
|
201
208
|
@client_addr = client
|
202
209
|
yield sock
|
203
210
|
end
|
204
211
|
end
|
205
212
|
end
|
206
213
|
|
207
|
-
def self.open host: nil, port: ::DEBUGGER__::CONFIG[:port], sock_dir: nil
|
208
|
-
if port
|
209
|
-
open_tcp host: host, port: port
|
210
|
-
else
|
211
|
-
open_unix sock_dir: sock_dir
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
def self.open_tcp(host: nil, port:)
|
216
|
-
initialize_session UI_TcpServer.new(host: host, port: port)
|
217
|
-
end
|
218
|
-
|
219
|
-
def self.open_unix sock_dir: nil
|
220
|
-
initialize_session UI_UnixDomainServer.new(sock_dir: sock_dir)
|
221
|
-
end
|
222
|
-
|
223
214
|
def self.message msg
|
224
215
|
$stderr.puts "DEBUGGER: #{msg}"
|
225
216
|
end
|
data/lib/debug/session.rb
CHANGED
@@ -1,18 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
FrameInfo = Struct.new(:location, :self, :binding, :iseq, :class, :frame_depth,
|
4
|
-
:has_return_value, :return_value, :show_line)
|
5
|
-
end
|
6
|
-
|
7
|
-
if File.exist? File.join(__dir__, 'debug.so')
|
8
|
-
require_relative 'debug.so'
|
9
|
-
else
|
10
|
-
require "debug/debug"
|
11
|
-
end
|
12
|
-
|
1
|
+
|
2
|
+
require_relative 'thread_client'
|
13
3
|
require_relative 'source_repository'
|
14
4
|
require_relative 'breakpoint'
|
15
|
-
require_relative 'thread_client'
|
16
5
|
require_relative 'config'
|
17
6
|
|
18
7
|
class RubyVM::InstructionSequence
|
@@ -61,7 +50,7 @@ module DEBUGGER__
|
|
61
50
|
@bps = {} # bp.key => bp
|
62
51
|
# [file, line] => LineBreakpoint
|
63
52
|
# "Error" => CatchBreakpoint
|
64
|
-
#
|
53
|
+
# "Foo#bar" => MethodBreakpoint
|
65
54
|
# [:watch, expr] => WatchExprBreakpoint
|
66
55
|
# [:check, expr] => CheckBreakpoint
|
67
56
|
@th_clients = {} # {Thread => ThreadClient}
|
@@ -73,7 +62,8 @@ module DEBUGGER__
|
|
73
62
|
|
74
63
|
@tp_load_script = TracePoint.new(:script_compiled){|tp|
|
75
64
|
ThreadClient.current.on_load tp.instruction_sequence, tp.eval_script
|
76
|
-
}
|
65
|
+
}
|
66
|
+
@tp_load_script.enable
|
77
67
|
|
78
68
|
@session_server = Thread.new do
|
79
69
|
Thread.current.abort_on_exception = true
|
@@ -149,7 +139,8 @@ module DEBUGGER__
|
|
149
139
|
|
150
140
|
@tp_thread_begin = TracePoint.new(:thread_begin){|tp|
|
151
141
|
ThreadClient.current.on_thread_begin Thread.current
|
152
|
-
}
|
142
|
+
}
|
143
|
+
@tp_thread_begin.enable
|
153
144
|
end
|
154
145
|
|
155
146
|
def add_initial_commands cmds
|
@@ -160,7 +151,11 @@ module DEBUGGER__
|
|
160
151
|
end
|
161
152
|
|
162
153
|
def source path
|
163
|
-
|
154
|
+
if CONFIG[:use_colorize]
|
155
|
+
@sr.get_colored(path)
|
156
|
+
else
|
157
|
+
@sr.get(path)
|
158
|
+
end
|
164
159
|
end
|
165
160
|
|
166
161
|
def inspect
|
@@ -409,17 +404,23 @@ module DEBUGGER__
|
|
409
404
|
|
410
405
|
@tc << [:show, :edit, arg]
|
411
406
|
|
412
|
-
# * `i[nfo]`
|
407
|
+
# * `i[nfo]`, `i[nfo] l[ocal[s]]`
|
413
408
|
# * Show information about the current frame (local variables)
|
414
409
|
# * It includes `self` as `%self` and a return value as `%return`.
|
415
|
-
# * `i[nfo]
|
416
|
-
# * Show
|
410
|
+
# * `i[nfo] th[read[s]]
|
411
|
+
# * Show all threads (same as `th[read]`).
|
417
412
|
when 'i', 'info'
|
418
413
|
case arg
|
419
414
|
when nil
|
420
415
|
@tc << [:show, :local]
|
416
|
+
when 'l', /locals?/
|
417
|
+
@tc << [:show, :local]
|
418
|
+
when 'th', /threads?/
|
419
|
+
thread_list
|
420
|
+
return :retry
|
421
421
|
else
|
422
|
-
|
422
|
+
show_help 'info'
|
423
|
+
return :retry
|
423
424
|
end
|
424
425
|
|
425
426
|
# * `display`
|
@@ -855,7 +856,7 @@ module DEBUGGER__
|
|
855
856
|
|
856
857
|
def add_catch_breakpoint arg
|
857
858
|
bp = CatchBreakpoint.new(arg)
|
858
|
-
|
859
|
+
add_breakpoint bp
|
859
860
|
end
|
860
861
|
|
861
862
|
def add_check_breakpoint expr
|
@@ -897,26 +898,37 @@ module DEBUGGER__
|
|
897
898
|
b = tp.binding
|
898
899
|
if var_name = b.local_variables.first
|
899
900
|
mid = b.local_variable_get(var_name)
|
900
|
-
|
901
|
+
unresolved = false
|
901
902
|
|
902
903
|
@bps.each{|k, bp|
|
903
904
|
case bp
|
904
905
|
when MethodBreakpoint
|
905
906
|
if bp.method.nil?
|
906
|
-
found = true
|
907
907
|
if bp.sig_method_name == mid.to_s
|
908
|
-
bp.
|
908
|
+
bp.try_enable(quiet: true)
|
909
909
|
end
|
910
910
|
end
|
911
|
+
|
912
|
+
unresolved = true unless bp.enabled?
|
911
913
|
end
|
912
914
|
}
|
913
|
-
unless
|
915
|
+
unless unresolved
|
914
916
|
METHOD_ADDED_TRACKER.disable
|
915
917
|
end
|
916
918
|
end
|
917
919
|
end
|
918
920
|
end
|
919
921
|
|
922
|
+
# manual configuration methods
|
923
|
+
|
924
|
+
def self.add_line_breakpoint file, line, **kw
|
925
|
+
::DEBUGGER__::SESSION.add_line_breakpoint file, line, **kw
|
926
|
+
end
|
927
|
+
|
928
|
+
def self.add_catch_breakpoint pat
|
929
|
+
::DEBUGGER__::SESSION.add_catch_breakpoint pat
|
930
|
+
end
|
931
|
+
|
920
932
|
# String for requring location
|
921
933
|
# nil for -r
|
922
934
|
def self.require_location
|
@@ -934,7 +946,12 @@ module DEBUGGER__
|
|
934
946
|
nil
|
935
947
|
end
|
936
948
|
|
937
|
-
|
949
|
+
# start methods
|
950
|
+
|
951
|
+
def self.console **kw
|
952
|
+
set_config(kw)
|
953
|
+
|
954
|
+
require_relative 'console'
|
938
955
|
initialize_session UI_Console.new
|
939
956
|
|
940
957
|
@prev_handler = trap(:SIGINT){
|
@@ -942,14 +959,30 @@ module DEBUGGER__
|
|
942
959
|
}
|
943
960
|
end
|
944
961
|
|
945
|
-
def self.
|
946
|
-
|
962
|
+
def self.open host: nil, port: ::DEBUGGER__::CONFIG[:port], sock_path: nil, sock_dir: nil, **kw
|
963
|
+
set_config(kw)
|
964
|
+
|
965
|
+
if port
|
966
|
+
open_tcp host: host, port: port
|
967
|
+
else
|
968
|
+
open_unix sock_path: sock_path, sock_dir: sock_dir
|
969
|
+
end
|
947
970
|
end
|
948
971
|
|
949
|
-
def self.
|
950
|
-
|
972
|
+
def self.open_tcp host: nil, port:, **kw
|
973
|
+
set_config(kw)
|
974
|
+
require_relative 'server'
|
975
|
+
initialize_session UI_TcpServer.new(host: host, port: port)
|
951
976
|
end
|
952
977
|
|
978
|
+
def self.open_unix sock_path: nil, sock_dir: nil, **kw
|
979
|
+
set_config(kw)
|
980
|
+
require_relative 'server'
|
981
|
+
initialize_session UI_UnixDomainServer.new(sock_dir: sock_dir, sock_path: sock_path)
|
982
|
+
end
|
983
|
+
|
984
|
+
# boot utilities
|
985
|
+
|
953
986
|
class << self
|
954
987
|
define_method :initialize_session do |ui|
|
955
988
|
::DEBUGGER__.const_set(:SESSION, Session.new(ui))
|
@@ -963,7 +996,7 @@ module DEBUGGER__
|
|
963
996
|
def bp; nil; end
|
964
997
|
end
|
965
998
|
|
966
|
-
if
|
999
|
+
if !::DEBUGGER__::CONFIG[:nonstop]
|
967
1000
|
if loc = ::DEBUGGER__.require_location
|
968
1001
|
# require 'debug/console' or 'debug'
|
969
1002
|
add_line_breakpoint loc.absolute_path, loc.lineno + 1, oneshot: true, hook_call: false
|
@@ -1052,8 +1085,6 @@ module DEBUGGER__
|
|
1052
1085
|
r.join("\n")
|
1053
1086
|
end
|
1054
1087
|
|
1055
|
-
CONFIG = ::DEBUGGER__.parse_argv(ENV['RUBY_DEBUG_OPT'])
|
1056
|
-
|
1057
1088
|
class ::Module
|
1058
1089
|
def method_added mid; end
|
1059
1090
|
def singleton_method_added mid; end
|
@@ -1,27 +1,57 @@
|
|
1
|
+
require 'irb/color' # IRB::Color.colorize_code
|
2
|
+
|
1
3
|
module DEBUGGER__
|
2
4
|
class SourceRepository
|
3
5
|
def initialize
|
4
6
|
@files = {} # filename => [src, iseq]
|
7
|
+
@color_files = {}
|
5
8
|
end
|
6
9
|
|
7
10
|
def add iseq, src
|
8
11
|
path = iseq.absolute_path
|
9
12
|
path = '-e' if iseq.path == '-e'
|
13
|
+
add_path path, src: src
|
14
|
+
end
|
10
15
|
|
16
|
+
def add_path path, src: nil
|
11
17
|
case
|
12
|
-
when
|
13
|
-
|
14
|
-
|
15
|
-
|
18
|
+
when src
|
19
|
+
if File.file?(path)
|
20
|
+
path = '(eval)' + path
|
21
|
+
src = nil
|
22
|
+
end
|
23
|
+
when path == '-e'
|
24
|
+
when path
|
25
|
+
begin
|
26
|
+
src = File.read(path)
|
27
|
+
rescue SystemCallError
|
28
|
+
end
|
16
29
|
else
|
17
30
|
src = nil
|
18
31
|
end
|
19
32
|
|
20
|
-
|
33
|
+
if src
|
34
|
+
src = src.gsub("\r\n", "\n") # CRLF -> LF
|
35
|
+
@files[path] = src.lines
|
36
|
+
end
|
21
37
|
end
|
22
38
|
|
23
39
|
def get path
|
24
|
-
@files
|
40
|
+
if @files.has_key? path
|
41
|
+
@files[path]
|
42
|
+
else
|
43
|
+
add_path path
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_colored path
|
48
|
+
if src_lines = @color_files[path]
|
49
|
+
return src_lines
|
50
|
+
else
|
51
|
+
if src_lines = get(path)
|
52
|
+
@color_files[path] = IRB::Color.colorize_code(src_lines.join).lines
|
53
|
+
end
|
54
|
+
end
|
25
55
|
end
|
26
56
|
end
|
27
57
|
end
|
data/lib/debug/thread_client.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'objspace'
|
2
2
|
require 'pp'
|
3
|
+
require 'irb/color'
|
4
|
+
require_relative 'frame_info'
|
3
5
|
|
4
6
|
module DEBUGGER__
|
5
7
|
class ThreadClient
|
@@ -12,6 +14,27 @@ module DEBUGGER__
|
|
12
14
|
|
13
15
|
attr_reader :location, :thread, :mode, :id
|
14
16
|
|
17
|
+
def colorize str, color
|
18
|
+
if CONFIG[:use_colorize]
|
19
|
+
IRB::Color.colorize str, color
|
20
|
+
else
|
21
|
+
str
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def default_frame_formatter frame
|
26
|
+
call_identifier_str = colorize(frame.call_identifier_str, [:BLUE, :BOLD])
|
27
|
+
location_str = colorize(frame.location_str, [:YELLOW])
|
28
|
+
result = "#{call_identifier_str} at #{location_str}"
|
29
|
+
|
30
|
+
if return_str = frame.return_str
|
31
|
+
return_str = colorize(frame.return_str, [:MAGENTA])
|
32
|
+
result += " #=> #{return_str}"
|
33
|
+
end
|
34
|
+
|
35
|
+
result
|
36
|
+
end
|
37
|
+
|
15
38
|
def initialize id, q_evt, q_cmd, thr = Thread.current
|
16
39
|
@id = id
|
17
40
|
@thread = thr
|
@@ -19,8 +42,9 @@ module DEBUGGER__
|
|
19
42
|
@q_cmd = q_cmd
|
20
43
|
@step_tp = nil
|
21
44
|
@output = []
|
22
|
-
@src_lines_on_stop = (DEBUGGER__::CONFIG[:show_src_lines] || 10).to_i
|
23
|
-
@show_frames_on_stop = (DEBUGGER__::CONFIG[:show_frames] || 2).to_i
|
45
|
+
@src_lines_on_stop = (::DEBUGGER__::CONFIG[:show_src_lines] || 10).to_i
|
46
|
+
@show_frames_on_stop = (::DEBUGGER__::CONFIG[:show_frames] || 2).to_i
|
47
|
+
@frame_formatter = method(:default_frame_formatter)
|
24
48
|
set_mode nil
|
25
49
|
end
|
26
50
|
|
@@ -129,7 +153,7 @@ module DEBUGGER__
|
|
129
153
|
next if SESSION.break? tp.path, tp.lineno
|
130
154
|
next if !yield
|
131
155
|
next if tp.path.start_with?(__dir__)
|
132
|
-
next unless File.exist?(tp.path) if CONFIG[:skip_nosrc]
|
156
|
+
next unless File.exist?(tp.path) if ::DEBUGGER__::CONFIG[:skip_nosrc]
|
133
157
|
|
134
158
|
tp.disable
|
135
159
|
on_suspend tp.event, tp
|
@@ -140,7 +164,7 @@ module DEBUGGER__
|
|
140
164
|
next if thread != Thread.current
|
141
165
|
next if SESSION.break? tp.path, tp.lineno
|
142
166
|
next if !yield
|
143
|
-
next unless File.exist?(tp.path) if CONFIG[:skip_nosrc]
|
167
|
+
next unless File.exist?(tp.path) if ::DEBUGGER__::CONFIG[:skip_nosrc]
|
144
168
|
|
145
169
|
tp.disable
|
146
170
|
on_suspend tp.event, tp
|
@@ -157,23 +181,15 @@ module DEBUGGER__
|
|
157
181
|
end
|
158
182
|
end
|
159
183
|
|
160
|
-
def file_lines path
|
161
|
-
if (src_lines = SESSION.source(path))
|
162
|
-
src_lines
|
163
|
-
elsif File.exist?(path)
|
164
|
-
File.readlines(path)
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
184
|
def show_src(frame_index: @current_frame_index,
|
169
185
|
update_line: false,
|
170
186
|
max_lines: 10,
|
171
187
|
start_line: nil,
|
172
188
|
end_line: nil,
|
173
189
|
dir: +1)
|
174
|
-
|
190
|
+
|
175
191
|
if @target_frames && frame = @target_frames[frame_index]
|
176
|
-
if file_lines =
|
192
|
+
if file_lines = frame.file_lines
|
177
193
|
frame_line = frame.location.lineno - 1
|
178
194
|
|
179
195
|
lines = file_lines.map.with_index do |e, i|
|
@@ -206,11 +222,11 @@ module DEBUGGER__
|
|
206
222
|
end
|
207
223
|
|
208
224
|
if start_line != end_line && max_lines
|
209
|
-
puts "[#{start_line+1}, #{end_line}] in #{pretty_path
|
225
|
+
puts "[#{start_line+1}, #{end_line}] in #{frame.pretty_path}" if !update_line && max_lines != 1
|
210
226
|
puts lines[start_line ... end_line]
|
211
227
|
end
|
212
228
|
else # no file lines
|
213
|
-
puts "# No sourcefile available for #{path}"
|
229
|
+
puts "# No sourcefile available for #{frame.path}"
|
214
230
|
end
|
215
231
|
end
|
216
232
|
end
|
@@ -218,7 +234,7 @@ module DEBUGGER__
|
|
218
234
|
def show_by_editor path = nil
|
219
235
|
unless path
|
220
236
|
if @target_frames && frame = @target_frames[@current_frame_index]
|
221
|
-
path = frame.
|
237
|
+
path = frame.path
|
222
238
|
else
|
223
239
|
return # can't get path
|
224
240
|
end
|
@@ -287,101 +303,12 @@ module DEBUGGER__
|
|
287
303
|
end
|
288
304
|
end
|
289
305
|
|
290
|
-
def
|
291
|
-
vars.map{|var|
|
292
|
-
begin
|
293
|
-
"#{var}=#{short_inspect(b.local_variable_get(var))}"
|
294
|
-
rescue NameError, TypeError
|
295
|
-
nil
|
296
|
-
end
|
297
|
-
}.compact.join(', ')
|
298
|
-
end
|
299
|
-
|
300
|
-
def get_singleton_class obj
|
301
|
-
obj.singleton_class # TODO: don't use it
|
302
|
-
rescue TypeError
|
303
|
-
nil
|
304
|
-
end
|
305
|
-
|
306
|
-
def klass_sig frame
|
307
|
-
klass = frame.class
|
308
|
-
if klass == get_singleton_class(frame.self)
|
309
|
-
"#{frame.self}."
|
310
|
-
else
|
311
|
-
"#{frame.class}#"
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
SHORT_INSPECT_LENGTH = 40
|
316
|
-
|
317
|
-
def short_inspect obj
|
318
|
-
str = obj.inspect
|
319
|
-
if str.length > SHORT_INSPECT_LENGTH
|
320
|
-
str[0...SHORT_INSPECT_LENGTH] + '...'
|
321
|
-
else
|
322
|
-
str
|
323
|
-
end
|
324
|
-
end
|
325
|
-
|
326
|
-
HOME = ENV['HOME'] ? (ENV['HOME'] + '/') : nil
|
327
|
-
|
328
|
-
def pretty_path path
|
329
|
-
use_short_path = CONFIG[:use_short_path]
|
330
|
-
|
331
|
-
case
|
332
|
-
when use_short_path && path.start_with?(dir = RbConfig::CONFIG["rubylibdir"] + '/')
|
333
|
-
path.sub(dir, '$(rubylibdir)/')
|
334
|
-
when use_short_path && Gem.path.any? do |gp|
|
335
|
-
path.start_with?(dir = gp + '/gems/')
|
336
|
-
end
|
337
|
-
path.sub(dir, '$(Gem)/')
|
338
|
-
when HOME && path.start_with?(HOME)
|
339
|
-
path.sub(HOME, '~/')
|
340
|
-
else
|
341
|
-
path
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|
345
|
-
def pretty_location loc
|
346
|
-
" at #{pretty_path(loc.path)}:#{loc.lineno}"
|
347
|
-
end
|
348
|
-
|
349
|
-
def frame_str i
|
350
|
-
frame = @target_frames[i]
|
351
|
-
b = frame.binding
|
352
|
-
|
306
|
+
def frame_str(i)
|
353
307
|
cur_str = (@current_frame_index == i ? '=>' : ' ')
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
args = parameters_info b, iseq.locals[0...argc]
|
359
|
-
args_str = "{|#{args}|}"
|
360
|
-
end
|
361
|
-
|
362
|
-
label_prefix = frame.location.label.sub('block'){ "block#{args_str}" }
|
363
|
-
ci_str = label_prefix
|
364
|
-
elsif (callee = b.eval('__callee__', __FILE__, __LINE__)) && (argc = iseq.argc) > 0
|
365
|
-
args = parameters_info b, iseq.locals[0...argc]
|
366
|
-
ksig = klass_sig frame
|
367
|
-
ci_str = "#{ksig}#{callee}(#{args})"
|
368
|
-
else
|
369
|
-
ci_str = frame.location.label
|
370
|
-
end
|
371
|
-
|
372
|
-
loc_str = "#{pretty_location(frame.location)}"
|
373
|
-
|
374
|
-
if frame.has_return_value
|
375
|
-
return_str = " #=> #{short_inspect(frame.return_value)}"
|
376
|
-
end
|
377
|
-
else
|
378
|
-
ksig = klass_sig frame
|
379
|
-
callee = frame.location.base_label
|
380
|
-
ci_str = "[C] #{ksig}#{callee}"
|
381
|
-
loc_str = "#{pretty_location(frame.location)}"
|
382
|
-
end
|
383
|
-
|
384
|
-
"#{cur_str}##{i}\t#{ci_str}#{loc_str}#{return_str}"
|
308
|
+
prefix = "#{cur_str}##{i}"
|
309
|
+
frame = @target_frames[i]
|
310
|
+
frame_string = @frame_formatter.call(frame)
|
311
|
+
"#{prefix}\t#{frame_string}"
|
385
312
|
end
|
386
313
|
|
387
314
|
def show_frames max = (@target_frames || []).size
|
@@ -457,7 +384,7 @@ module DEBUGGER__
|
|
457
384
|
step_tp{true}
|
458
385
|
when :next
|
459
386
|
frame = @target_frames.first
|
460
|
-
path = frame.location.absolute_path || "!eval:#{frame.
|
387
|
+
path = frame.location.absolute_path || "!eval:#{frame.path}"
|
461
388
|
line = frame.location.lineno
|
462
389
|
frame.iseq.traceable_lines_norec(lines = {})
|
463
390
|
next_line = lines.keys.bsearch{|e| e > line}
|
@@ -533,7 +460,7 @@ module DEBUGGER__
|
|
533
460
|
case type
|
534
461
|
when :up
|
535
462
|
if @current_frame_index + 1 < @target_frames.size
|
536
|
-
@current_frame_index += 1
|
463
|
+
@current_frame_index += 1
|
537
464
|
show_src max_lines: 1
|
538
465
|
show_frame(@current_frame_index)
|
539
466
|
end
|
data/lib/debug/version.rb
CHANGED
data/misc/README.md.erb
CHANGED
@@ -62,13 +62,14 @@ $ ruby -r debug/run target.rb
|
|
62
62
|
|
63
63
|
$ cat target.rb
|
64
64
|
require 'debug/run' # start the debug console
|
65
|
-
...
|
65
|
+
... rest of program ...
|
66
66
|
|
67
67
|
# or
|
68
68
|
|
69
69
|
$ cat target.rb
|
70
70
|
require 'debug/session' # introduce the functionality
|
71
71
|
DEBUGGER__.console # and start the debug console
|
72
|
+
... rest of program ...
|
72
73
|
|
73
74
|
$ ruby target.rb
|
74
75
|
```
|
@@ -295,10 +296,10 @@ You can control debuggee's behavior with environment variables:
|
|
295
296
|
* `RUBY_DEBUG_COMMANDS`: Debug commands invoked at the first stop. Commands should be separated by ';;'.
|
296
297
|
* `RUBY_DEBUG_SHOW_SRC_LINES`: Show n lines source code on breakpoint (default: 10 lines).
|
297
298
|
* `RUBY_DEBUG_SHOW_FRAMES`: Show n frames on breakpoint (default: 2 frames).
|
298
|
-
|
299
299
|
* Remote debugging
|
300
300
|
* `RUBY_DEBUG_PORT`: TCP/IP remote debugging: port to open.
|
301
301
|
* `RUBY_DEBUG_HOST`: TCP/IP remote debugging: host (localhost if not given) to open.
|
302
|
+
* `RUBY_DEBUG_SOCK_PATH`: UNIX Domain Socket remote debugging: socket path to open.
|
302
303
|
* `RUBY_DEBUG_SOCK_DIR`: UNIX Domain Socket remote debugging: socket directory to open.
|
303
304
|
|
304
305
|
## Debug command on the debug console
|
@@ -322,3 +323,5 @@ The `<...>` notation means the argument.
|
|
322
323
|
# Contributing
|
323
324
|
|
324
325
|
Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/debug.
|
326
|
+
|
327
|
+
Please also check the [contributing guideline](/CONTRIBUTING.md).
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: debug
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.beta4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Koichi Sasada
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-05-
|
11
|
+
date: 2021-05-25 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Debugging functionality for Ruby. This is completely rewritten debug.rb
|
14
14
|
which was contained by the encient Ruby versions.
|
@@ -21,10 +21,12 @@ extensions:
|
|
21
21
|
extra_rdoc_files: []
|
22
22
|
files:
|
23
23
|
- ".gitignore"
|
24
|
+
- CONTRIBUTING.md
|
24
25
|
- Gemfile
|
25
26
|
- LICENSE.txt
|
26
27
|
- README.md
|
27
28
|
- Rakefile
|
29
|
+
- TODO.md
|
28
30
|
- bin/console
|
29
31
|
- bin/setup
|
30
32
|
- debug.gemspec
|
@@ -38,6 +40,7 @@ files:
|
|
38
40
|
- lib/debug/client.rb
|
39
41
|
- lib/debug/config.rb
|
40
42
|
- lib/debug/console.rb
|
43
|
+
- lib/debug/frame_info.rb
|
41
44
|
- lib/debug/open.rb
|
42
45
|
- lib/debug/run.rb
|
43
46
|
- lib/debug/server.rb
|