debug 0.2.1 → 1.0.0.alpha0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/LICENSE.txt +19 -20
- data/README.md +142 -28
- data/Rakefile +9 -0
- data/debug.gemspec +20 -10
- data/exe/rdbg +3 -0
- data/lib/debug/bp.vim +68 -0
- data/lib/debug/breakpoint.rb +97 -0
- data/lib/debug/client.rb +135 -0
- data/lib/debug/config.rb +26 -0
- data/lib/debug/repl.rb +67 -0
- data/lib/debug/server.rb +119 -0
- data/lib/debug/session.rb +598 -0
- data/lib/debug/source_repository.rb +20 -0
- data/lib/debug/tcpserver.rb +23 -0
- data/lib/debug/thread_client.rb +402 -0
- data/lib/debug/unixserver.rb +19 -0
- data/lib/debug/version.rb +3 -0
- data/lib/debug.rb +11 -1116
- metadata +61 -21
- data/Gemfile +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58f91a1d4079133e3e7590329d65b7b811490f7158ef96d7b3f826968bc3ad1f
|
4
|
+
data.tar.gz: 4da17de6911dc4506cb869298d84df46de08121aca704bb9e2643f774015fbb3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: baa1a1708b02b63f47d7d751ce9e5830edcdc690c8ca84c956f0e4ce839db5f3f63cf22e856ad4cec43190bb7401b8dcfd13a3d55de72d0a438520a3fab394bc
|
7
|
+
data.tar.gz: 3816a302b56757b55501950ff2814e21d978a5cdf58a4431d663bd1dfbdaae1c7652e0a9565e4401201b29119cdfaa35f47986eee1b17b0b60c1759ec21f3e6a
|
data/.gitignore
CHANGED
data/LICENSE.txt
CHANGED
@@ -1,22 +1,21 @@
|
|
1
|
-
|
1
|
+
The MIT License (MIT)
|
2
2
|
|
3
|
-
|
4
|
-
modification, are permitted provided that the following conditions
|
5
|
-
are met:
|
6
|
-
1. Redistributions of source code must retain the above copyright
|
7
|
-
notice, this list of conditions and the following disclaimer.
|
8
|
-
2. Redistributions in binary form must reproduce the above copyright
|
9
|
-
notice, this list of conditions and the following disclaimer in the
|
10
|
-
documentation and/or other materials provided with the distribution.
|
3
|
+
Copyright (c) 2021 Koichi Sasada
|
11
4
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,52 +1,166 @@
|
|
1
|
-
#
|
1
|
+
# debug.rb
|
2
2
|
|
3
|
-
|
3
|
+
## How to install
|
4
4
|
|
5
|
-
|
5
|
+
This is temporary installation guide until gemify.
|
6
6
|
|
7
|
-
|
7
|
+
```
|
8
|
+
$ git clone https://github.com/ko1/debug.git
|
9
|
+
$ gem install debug_inspector
|
10
|
+
$ gem install iseq_collector
|
11
|
+
$ export RUBYOPT=-I`pwd`/debug/lib
|
12
|
+
# or add "-I`pwd`/debug/lib" for the following command
|
13
|
+
```
|
14
|
+
|
15
|
+
# How to use
|
16
|
+
|
17
|
+
## Invoke with debugger
|
18
|
+
|
19
|
+
### REPL debug
|
8
20
|
|
9
|
-
```
|
10
|
-
|
21
|
+
```
|
22
|
+
$ ruby -r debug target.rb
|
11
23
|
```
|
12
24
|
|
13
|
-
|
25
|
+
and you can see the debugger prompt. The program was suspended at the beggining of target.rb. To continue the program, type `c` (or `continue`). See other debug commands below.
|
14
26
|
|
15
|
-
|
27
|
+
You can re-enable debug command mode by `Ctrl-C`.
|
16
28
|
|
17
|
-
|
29
|
+
### Remote debug (1) UNIX domain socket
|
18
30
|
|
19
|
-
|
31
|
+
```
|
32
|
+
$ ruby -r debug/unixserver target.rb
|
33
|
+
```
|
20
34
|
|
21
|
-
|
35
|
+
It runs target.rb and accept debugger connection within UNIX domain socket.
|
22
36
|
|
23
|
-
|
24
|
-
program:
|
37
|
+
You can attach the program with the folliowing command:
|
25
38
|
|
26
|
-
```
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
39
|
+
```
|
40
|
+
$ ruby -r debug/client -e connect
|
41
|
+
Debugger can attach via UNIX domain socket (/home/ko1/.ruby-debug-sock/ruby-debug-ko1-20642)
|
42
|
+
...
|
31
43
|
```
|
32
44
|
|
33
|
-
|
34
|
-
method is run.
|
45
|
+
The debugee process will be suspended and wait for the debug command.
|
35
46
|
|
36
|
-
|
47
|
+
If you are running multiple debuggee processes, this command shows the selection like that:
|
37
48
|
|
38
49
|
```
|
39
|
-
|
40
|
-
|
50
|
+
$ ruby -r debug/client -e connect
|
51
|
+
Please select a debug session:
|
52
|
+
ruby-debug-ko1-19638
|
53
|
+
ruby-debug-ko1-19603
|
41
54
|
```
|
42
55
|
|
43
|
-
|
56
|
+
and you need to specify one:
|
44
57
|
|
45
|
-
|
58
|
+
```
|
59
|
+
$ ruby -r debug/client -e connect ruby-debug-ko1-19638
|
60
|
+
```
|
61
|
+
|
62
|
+
The socket file is located at
|
63
|
+
* `RUBY_DEBUG_SOCK_DIR` environment variable if available.
|
64
|
+
* `XDG_RUNTIME_DIR` environment variable if available.
|
65
|
+
* `$HOME/ruby-debug-sock` if `$HOME` is available.
|
46
66
|
|
47
|
-
|
67
|
+
### Remote debug (2) TCP/IP
|
48
68
|
|
49
|
-
|
69
|
+
```
|
70
|
+
$ RUBY_DEBUG_PORT=12345 RUBY_DEBUG_HOST=localhost ruby -r debug/tcpserver target.rb
|
71
|
+
Debugger can attach via TCP/IP (localhost:12345)
|
72
|
+
...
|
73
|
+
```
|
74
|
+
|
75
|
+
This command invoke target.rb with TCP/IP attach server with given port and host. If host is not given, `localhost` will be used.
|
76
|
+
|
77
|
+
```
|
78
|
+
$ ruby -r debug/client -e connect localhost 12345
|
79
|
+
```
|
50
80
|
|
51
|
-
|
81
|
+
tries to connect with given host (`localhost`) and port (`12345`). You can eliminate host part and `localhost` will be used.
|
82
|
+
|
83
|
+
|
84
|
+
## Debug command
|
85
|
+
|
86
|
+
* `Enter` repeats the last command (useful when repeating `step`s).
|
87
|
+
* `Ctrl-D` is equal to `quit` command.
|
88
|
+
|
89
|
+
### Control flow
|
90
|
+
|
91
|
+
* `s[tep]`
|
92
|
+
* Step in. Resume the program until next breakable point.
|
93
|
+
* `n[ext]`
|
94
|
+
* Step over. Resume the program until next line.
|
95
|
+
* `fin[ish]`
|
96
|
+
* Finish this frame. Resume the program until the current frame is finished.
|
97
|
+
* `c[ontinue]`
|
98
|
+
* Resume the program.
|
99
|
+
* `q[uit]` or `Ctrl-D`
|
100
|
+
* Finish debugger (with a process, if not remote debugging).
|
101
|
+
* `kill`
|
102
|
+
* Stop the debuggee program.
|
103
|
+
|
104
|
+
### Breakpoint
|
105
|
+
|
106
|
+
* `b[reak]`
|
107
|
+
* Show all breakpoints.
|
108
|
+
* `b[reak] <line>`
|
109
|
+
* Set breakpoint on `<line>` at the current frame's file.
|
110
|
+
* `b[reak] <file>:<line>`
|
111
|
+
* Set breakpoint on `<file>:<line>`.
|
112
|
+
* `catch <Error>`
|
113
|
+
* Set breakpoint on raising `<Error>`.
|
114
|
+
* `del[ete]`
|
115
|
+
* delete all breakpoints.
|
116
|
+
* `del[ete] <bpnum>`
|
117
|
+
* delete specified breakpoint.
|
118
|
+
|
119
|
+
### Frame control
|
120
|
+
|
121
|
+
* `bt` or `backtrace`
|
122
|
+
* Show backtrace information.
|
123
|
+
* `f[rame]`
|
124
|
+
* Show current frame.
|
125
|
+
* `f[rame] <framenum>`
|
126
|
+
* Specify frame. Evaluation are run on this frame environement.
|
127
|
+
* `up`
|
128
|
+
* Specify upper frame.
|
129
|
+
* `down`
|
130
|
+
* Specify down frame.
|
131
|
+
|
132
|
+
### Evaluate
|
133
|
+
|
134
|
+
* `p <expr>`
|
135
|
+
* Evaluate like `p <expr>` on the current frame.
|
136
|
+
* `pp <expr>`
|
137
|
+
* Evaluate like `pp <expr>` on the current frame.
|
138
|
+
* `e[val] <expr>`
|
139
|
+
* Evaluate `<expr>` on the current frame.
|
140
|
+
|
141
|
+
### Information
|
142
|
+
|
143
|
+
* `list`
|
144
|
+
* Show current frame's source code.
|
145
|
+
* `info l[ocal[s]]`
|
146
|
+
* Show current frame's local variables. It includes `self` as `%self` and a return value as `%return`.
|
147
|
+
* `info i[nstance]` or `info ivars`
|
148
|
+
* Show current frame's insntance variables.
|
149
|
+
* `display`
|
150
|
+
* Show display setting.
|
151
|
+
* `display <expr>`
|
152
|
+
* Add `<expr>` at suspended timing.
|
153
|
+
* `undisplay`
|
154
|
+
* Remove all display settings.
|
155
|
+
* `undisplay <displaynum>`
|
156
|
+
* Remove a specified display setting.
|
157
|
+
* `trace [on|off]`
|
158
|
+
* enable or disable line tracer.
|
159
|
+
|
160
|
+
### Thread control
|
161
|
+
|
162
|
+
* `th[read] [l[ist]]`
|
163
|
+
* Show all threads.
|
164
|
+
* `th[read] <thnum>`
|
165
|
+
* Switch thread specified by `<thnum>`
|
52
166
|
|
data/Rakefile
CHANGED
data/debug.gemspec
CHANGED
@@ -1,22 +1,32 @@
|
|
1
|
+
require_relative 'lib/debug/version'
|
2
|
+
|
1
3
|
Gem::Specification.new do |spec|
|
2
4
|
spec.name = "debug"
|
3
|
-
spec.version =
|
4
|
-
spec.authors = ["
|
5
|
-
spec.email = ["
|
5
|
+
spec.version = DEBUGGER__::VERSION
|
6
|
+
spec.authors = ["Koichi Sasada"]
|
7
|
+
spec.email = ["ko1@atdot.net"]
|
8
|
+
|
9
|
+
spec.summary = %q{debug.rb}
|
10
|
+
spec.description = %q{debug.rb}
|
11
|
+
spec.homepage = "https://github.com/ko1/debug"
|
12
|
+
spec.license = "MIT"
|
13
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
|
6
14
|
|
7
|
-
spec.
|
8
|
-
spec.description = %q{Debugging functionality for Ruby}
|
9
|
-
spec.homepage = "https://github.com/ruby/debug"
|
10
|
-
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
11
|
-
spec.licenses = ["Ruby", "BSD-2-Clause"]
|
15
|
+
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
12
16
|
|
13
17
|
spec.metadata["homepage_uri"] = spec.homepage
|
14
|
-
spec.metadata["source_code_uri"] =
|
18
|
+
spec.metadata["source_code_uri"] = "https://github.com/ko1/debug"
|
19
|
+
# spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
|
15
20
|
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
16
23
|
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
17
24
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
25
|
end
|
19
26
|
spec.bindir = "exe"
|
20
|
-
spec.executables =
|
27
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
28
|
spec.require_paths = ["lib"]
|
29
|
+
|
30
|
+
spec.add_runtime_dependency 'debug_inspector'
|
31
|
+
spec.add_runtime_dependency 'iseq_collector'
|
22
32
|
end
|
data/exe/rdbg
ADDED
data/lib/debug/bp.vim
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
let g:rdb_bps = {}
|
2
|
+
|
3
|
+
function SET_BP()
|
4
|
+
let signed = sign_getplaced(bufname(), {'lnum': line('.')})
|
5
|
+
if empty(signed[0]['signs'])
|
6
|
+
call sign_place(0, '', 'signBP', bufname(), {'lnum': line('.')})
|
7
|
+
else
|
8
|
+
"echo signed[0]['signs']
|
9
|
+
call sign_unplace('', {'buffer': bufname(), 'id': signed[0]['signs'][0]['id']})
|
10
|
+
endif
|
11
|
+
endfunction
|
12
|
+
|
13
|
+
function UPDATE_BPS()
|
14
|
+
let signs = sign_getplaced(bufname())
|
15
|
+
let key = expand('%:p')
|
16
|
+
|
17
|
+
if empty(signs[0]['signs'])
|
18
|
+
let removed = remove(g:rdb_bps, key)
|
19
|
+
else
|
20
|
+
let g:rdb_bps[key] = signs[0]['signs']
|
21
|
+
endif
|
22
|
+
endfunction
|
23
|
+
|
24
|
+
function APPLY_BPS()
|
25
|
+
let key = expand('%:p')
|
26
|
+
if has_key(g:rdb_bps, key)
|
27
|
+
for b in g:rdb_bps[key]
|
28
|
+
call sign_place(0, '', 'signBP', bufname(), {'lnum': b['lnum']})
|
29
|
+
endfor
|
30
|
+
endif
|
31
|
+
endfunction
|
32
|
+
|
33
|
+
function WRITE_BPS()
|
34
|
+
call writefile([json_encode(g:rdb_bps)], '.rdb_breakpoints.json')
|
35
|
+
endfunction
|
36
|
+
|
37
|
+
" load
|
38
|
+
try
|
39
|
+
let json = readfile('.rdb_breakpoints.json')
|
40
|
+
let g:rdb_bps = json_decode(json[0])
|
41
|
+
" {"/full/path/to/file1": [{"lnum": 10}, ...], ...}
|
42
|
+
catch /Can't open/
|
43
|
+
let g:rdb_bps = {}
|
44
|
+
catch /Invalid arguments for function json_decode/
|
45
|
+
let g:rdb_bps = {}
|
46
|
+
endtry
|
47
|
+
|
48
|
+
sign define signBP text=BR
|
49
|
+
|
50
|
+
call APPLY_BPS()
|
51
|
+
|
52
|
+
autocmd BufReadPost * call APPLY_BPS()
|
53
|
+
autocmd BufUnload * call UPDATE_BPS()
|
54
|
+
autocmd VimLeave * call WRITE_BPS()
|
55
|
+
|
56
|
+
function! s:ruby_bp_settings() abort
|
57
|
+
echomsg "Type <Space> to toggle break points and <q> to quit"
|
58
|
+
|
59
|
+
if &readonly
|
60
|
+
nnoremap <silent> <buffer> <Space> :call SET_BP()<CR>
|
61
|
+
nnoremap <silent> <buffer> q :<C-u>quit<CR>
|
62
|
+
endif
|
63
|
+
endfunction
|
64
|
+
|
65
|
+
" autocmd FileType ruby call s:ruby_bp_settings()
|
66
|
+
autocmd BufEnter *.rb call s:ruby_bp_settings()
|
67
|
+
|
68
|
+
call s:ruby_bp_settings()
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module DEBUGGER__
|
2
|
+
class LineBreakpoint
|
3
|
+
attr_reader :path, :line, :key
|
4
|
+
|
5
|
+
def initialize type, iseq, line, cond = nil, oneshot: false
|
6
|
+
@iseq = iseq
|
7
|
+
@path = iseq.path
|
8
|
+
@line = line
|
9
|
+
@type = type
|
10
|
+
@cond = cond
|
11
|
+
@oneshot = oneshot
|
12
|
+
@key = [@path, @line].freeze
|
13
|
+
setup
|
14
|
+
enable
|
15
|
+
end
|
16
|
+
|
17
|
+
def safe_eval b, expr
|
18
|
+
b.eval(expr)
|
19
|
+
rescue Exception => e
|
20
|
+
puts "[EVAL ERROR]"
|
21
|
+
puts " expr: #{expr}"
|
22
|
+
puts " err: #{e} (#{e.class})"
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def setup
|
27
|
+
if !@cond
|
28
|
+
@tp = TracePoint.new(@type) do |tp|
|
29
|
+
tp.disable if @oneshot
|
30
|
+
ThreadClient.current.on_breakpoint tp
|
31
|
+
end
|
32
|
+
else
|
33
|
+
@tp = TracePoint.new(@type) do |tp|
|
34
|
+
next unless safe_eval tp.binding, @cond
|
35
|
+
tp.disable if @oneshot
|
36
|
+
ThreadClient.current.on_breakpoint tp
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def enable
|
42
|
+
if @type == :line
|
43
|
+
@tp.enable(target: @iseq, target_line: @line)
|
44
|
+
else
|
45
|
+
@tp.enable(target: @iseq)
|
46
|
+
end
|
47
|
+
rescue ArgumentError
|
48
|
+
puts @iseq.disasm # for debug
|
49
|
+
raise
|
50
|
+
end
|
51
|
+
|
52
|
+
def disable
|
53
|
+
@tp.disable
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_s
|
57
|
+
"line bp #{@iseq.absolute_path}:#{@line} (#{@type})" +
|
58
|
+
if @cond
|
59
|
+
"if #{@cond}"
|
60
|
+
else
|
61
|
+
""
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def inspect
|
66
|
+
"<#{self.class.name} #{self.to_s}>"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class CatchBreakpoint
|
71
|
+
attr_reader :key
|
72
|
+
|
73
|
+
def initialize pat
|
74
|
+
@pat = pat
|
75
|
+
@tp = TracePoint.new(:raise){|tp|
|
76
|
+
exc = tp.raised_exception
|
77
|
+
exc.class.ancestors.each{|cls|
|
78
|
+
if pat === cls.name
|
79
|
+
puts "catch #{exc.class.inspect} by #{@pat.inspect}"
|
80
|
+
ThreadClient.current.on_suspend :catch
|
81
|
+
end
|
82
|
+
}
|
83
|
+
}
|
84
|
+
@tp.enable
|
85
|
+
|
86
|
+
@key = pat.freeze
|
87
|
+
end
|
88
|
+
|
89
|
+
def disable
|
90
|
+
@tp.disable
|
91
|
+
end
|
92
|
+
|
93
|
+
def to_s
|
94
|
+
"catch bp #{@pat.inspect}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/lib/debug/client.rb
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require_relative 'config'
|
3
|
+
|
4
|
+
module DEBUGGER__
|
5
|
+
class Client
|
6
|
+
begin
|
7
|
+
require 'readline'
|
8
|
+
def readline
|
9
|
+
Readline.readline("\n(rdb) ", true)
|
10
|
+
end
|
11
|
+
rescue LoadError
|
12
|
+
def readline
|
13
|
+
print "\n(rdb) "
|
14
|
+
gets
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def help
|
19
|
+
puts "-run -e attach # connect via UNIX Domain socket"
|
20
|
+
puts "-run -e attach name # connect via UNIX Domain socket with specified name"
|
21
|
+
puts "-run -e attach port_num # connect via TCP/IP socket with specified port"
|
22
|
+
puts "-run -e attach host port_num"
|
23
|
+
puts " # connect via TCP/IP socket with specified host and port"
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize argv
|
27
|
+
case argv.size
|
28
|
+
when 0
|
29
|
+
connect_unix
|
30
|
+
when 1
|
31
|
+
case arg = argv.shift
|
32
|
+
when /-h/, /--help/
|
33
|
+
help
|
34
|
+
exit
|
35
|
+
when /\A\d+\z/
|
36
|
+
connect_tcp nil, arg.to_i
|
37
|
+
else
|
38
|
+
connect_unix arg
|
39
|
+
end
|
40
|
+
when 2
|
41
|
+
connect_tcp argv[0], argv[1]
|
42
|
+
else
|
43
|
+
help
|
44
|
+
exit!
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def cleanup_unix_domain_sockets
|
49
|
+
Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*') do |file|
|
50
|
+
if /(\d+)$/ =~ file
|
51
|
+
begin
|
52
|
+
Process.kill(0, $1.to_i)
|
53
|
+
rescue Errno::ESRCH
|
54
|
+
File.unlink(file)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def connect_unix name = nil
|
61
|
+
if name
|
62
|
+
if File.exist? name
|
63
|
+
@s = Socket.unix(name)
|
64
|
+
else
|
65
|
+
@s = Socket.unix(File.join(DEBUGGER__.unix_domain_socket_basedir, name))
|
66
|
+
end
|
67
|
+
else
|
68
|
+
cleanup_unix_domain_sockets
|
69
|
+
files = Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*')
|
70
|
+
case files.size
|
71
|
+
when 0
|
72
|
+
$stderr.puts "There is no debug sessions."
|
73
|
+
exit
|
74
|
+
when 1
|
75
|
+
@s = Socket.unix(files.first)
|
76
|
+
else
|
77
|
+
$stderr.puts "Please select a debug session:"
|
78
|
+
files.each{|f|
|
79
|
+
$stderr.puts " #{File.basename(f)}"
|
80
|
+
}
|
81
|
+
exit
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def connect_tcp host, port
|
87
|
+
@s = Socket.tcp(host, port)
|
88
|
+
end
|
89
|
+
|
90
|
+
def connect
|
91
|
+
trap(:SIGINT){
|
92
|
+
@s.puts "pause"
|
93
|
+
}
|
94
|
+
|
95
|
+
while line = @s.gets
|
96
|
+
# p line: line
|
97
|
+
case line
|
98
|
+
when /^out (.*)/
|
99
|
+
puts "#{$1}"
|
100
|
+
when /^input/
|
101
|
+
prev_trap = trap(:SIGINT, 'DEFAULT')
|
102
|
+
|
103
|
+
begin
|
104
|
+
line = readline
|
105
|
+
rescue Interrupt
|
106
|
+
retry
|
107
|
+
ensure
|
108
|
+
trap(:SIGINT, prev_trap)
|
109
|
+
end
|
110
|
+
|
111
|
+
line = (line || 'quit').strip
|
112
|
+
@s.puts "command #{line}"
|
113
|
+
when /^ask (.*)/
|
114
|
+
print $1
|
115
|
+
@s.puts "answer #{gets || ''}"
|
116
|
+
when /^quit/
|
117
|
+
raise 'quit'
|
118
|
+
else
|
119
|
+
puts "(unknown) #{line.inspect}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
rescue
|
123
|
+
STDERR.puts "disconnected (#{$!})"
|
124
|
+
exit
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def connect argv = ARGV
|
130
|
+
DEBUGGER__::Client.new(argv).connect
|
131
|
+
end
|
132
|
+
|
133
|
+
if __FILE__ == $0
|
134
|
+
connect
|
135
|
+
end
|
data/lib/debug/config.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module DEBUGGER__
|
2
|
+
def self.unix_domain_socket_basedir
|
3
|
+
case
|
4
|
+
when path = ENV['RUBY_DEBUG_SOCK_DIR']
|
5
|
+
when path = ENV['XDG_RUNTIME_DIR']
|
6
|
+
when home = ENV['HOME']
|
7
|
+
path = File.join(home, '.ruby-debug-sock')
|
8
|
+
unless File.exist?(path)
|
9
|
+
Dir.mkdir(path, 0700)
|
10
|
+
end
|
11
|
+
else
|
12
|
+
raise 'specify RUBY_DEBUG_SOCK_DIR environment variable for UNIX domain socket directory.'
|
13
|
+
end
|
14
|
+
|
15
|
+
path
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.create_unix_domain_socket_name_prefix
|
19
|
+
user = ENV['USER'] || 'ruby-debug'
|
20
|
+
File.join(unix_domain_socket_basedir, "ruby-debug-#{user}")
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.create_unix_domain_socket_name
|
24
|
+
create_unix_domain_socket_name_prefix + "-#{Process.pid}"
|
25
|
+
end
|
26
|
+
end
|