debug 0.2.1 → 1.0.0.alpha0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|