rudebug 0.3.0 → 0.3.1
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.
- data/COPYING +56 -56
- data/NEWS +10 -6
- data/README +31 -31
- data/bin/rudebug +4 -4
- data/lib/rudebug/connect.rb +203 -203
- data/lib/rudebug/connection/base.rb +109 -109
- data/lib/rudebug/connection/breakpoint.rb +109 -109
- data/lib/rudebug/connection/ruby-debug.rb +133 -133
- data/lib/rudebug/gtk-patch.rb +5 -3
- metadata +1 -1
@@ -1,109 +1,109 @@
|
|
1
|
-
class Connection
|
2
|
-
class RemoteException < Exception
|
3
|
-
end
|
4
|
-
|
5
|
-
class Base
|
6
|
-
attr_accessor :on_session, :on_disconnect
|
7
|
-
|
8
|
-
Code = <<-END_CODE
|
9
|
-
$rudebug = Module.new do
|
10
|
-
extend self
|
11
|
-
|
12
|
-
def inspect()
|
13
|
-
"$rudebug"
|
14
|
-
end
|
15
|
-
alias :name :inspect
|
16
|
-
|
17
|
-
attr_accessor :selected
|
18
|
-
|
19
|
-
const_set(:Refs, [])
|
20
|
-
|
21
|
-
def add_ref(ref)
|
22
|
-
$rudebug::Refs << ref
|
23
|
-
return ref
|
24
|
-
end
|
25
|
-
|
26
|
-
const_set(:Pairs, Class.new {
|
27
|
-
def self.[](*pairs)
|
28
|
-
new(*pairs)
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.to_s()
|
32
|
-
"$rudebug::Pairs"
|
33
|
-
end
|
34
|
-
|
35
|
-
def initialize(*pairs)
|
36
|
-
@pairs = pairs
|
37
|
-
end
|
38
|
-
|
39
|
-
def inspect()
|
40
|
-
"{ %s }" % @pairs.map do |key, value|
|
41
|
-
[
|
42
|
-
key.is_a?(Numeric) ? key : key.to_sym.inspect,
|
43
|
-
$rudebug.inspect_obj(value)
|
44
|
-
].join(" => ")
|
45
|
-
end.join(", ")
|
46
|
-
end
|
47
|
-
|
48
|
-
def each(&block)
|
49
|
-
@pairs.each(&block)
|
50
|
-
end
|
51
|
-
|
52
|
-
def size()
|
53
|
-
@pairs.size
|
54
|
-
end
|
55
|
-
|
56
|
-
include Enumerable
|
57
|
-
})
|
58
|
-
|
59
|
-
def to_pairs(items, &block)
|
60
|
-
$rudebug::Pairs[*items.map { |item| [item, block.call(item)] }]
|
61
|
-
end
|
62
|
-
|
63
|
-
def to_list(items)
|
64
|
-
to_pairs(0 .. items.size - 1) { |idx| items[idx] }
|
65
|
-
end
|
66
|
-
|
67
|
-
def inspect_obj(obj)
|
68
|
-
case obj
|
69
|
-
when UnboundMethod, Method then
|
70
|
-
inspect_method(obj)
|
71
|
-
else
|
72
|
-
#require 'pp'
|
73
|
-
#PP.pp(obj, "", 30).chomp
|
74
|
-
obj.inspect
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def inspect_method(method)
|
79
|
-
re = /^\x23<(?:Unbound)?Method: ([^(]+)(?:\\(([^)]+)\\))?\x23(.+?)>$/
|
80
|
-
if md = re.match(method.inspect) then
|
81
|
-
klass, diff_origin, name = *md.captures
|
82
|
-
origin = diff_origin || klass
|
83
|
-
argc = method.arity
|
84
|
-
more = argc < 0
|
85
|
-
argc = -argc if more
|
86
|
-
|
87
|
-
old_name = "a"
|
88
|
-
args = (1 .. argc).map do |idx|
|
89
|
-
arg_name = old_name.dup
|
90
|
-
old_name.succ!
|
91
|
-
arg_name
|
92
|
-
end
|
93
|
-
args[-1][0, 0] = "*" if more
|
94
|
-
|
95
|
-
"%s\x23%s(%s)" % [origin, name, args.join(", ")]
|
96
|
-
else
|
97
|
-
method.inspect
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
END_CODE
|
102
|
-
|
103
|
-
def self.load_rudebug_code(session)
|
104
|
-
session.eval(Code)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
eval(Connection::Base::Code)
|
1
|
+
class Connection
|
2
|
+
class RemoteException < Exception
|
3
|
+
end
|
4
|
+
|
5
|
+
class Base
|
6
|
+
attr_accessor :on_session, :on_disconnect
|
7
|
+
|
8
|
+
Code = <<-END_CODE
|
9
|
+
$rudebug = Module.new do
|
10
|
+
extend self
|
11
|
+
|
12
|
+
def inspect()
|
13
|
+
"$rudebug"
|
14
|
+
end
|
15
|
+
alias :name :inspect
|
16
|
+
|
17
|
+
attr_accessor :selected
|
18
|
+
|
19
|
+
const_set(:Refs, [])
|
20
|
+
|
21
|
+
def add_ref(ref)
|
22
|
+
$rudebug::Refs << ref
|
23
|
+
return ref
|
24
|
+
end
|
25
|
+
|
26
|
+
const_set(:Pairs, Class.new {
|
27
|
+
def self.[](*pairs)
|
28
|
+
new(*pairs)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.to_s()
|
32
|
+
"$rudebug::Pairs"
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(*pairs)
|
36
|
+
@pairs = pairs
|
37
|
+
end
|
38
|
+
|
39
|
+
def inspect()
|
40
|
+
"{ %s }" % @pairs.map do |key, value|
|
41
|
+
[
|
42
|
+
key.is_a?(Numeric) ? key : key.to_sym.inspect,
|
43
|
+
$rudebug.inspect_obj(value)
|
44
|
+
].join(" => ")
|
45
|
+
end.join(", ")
|
46
|
+
end
|
47
|
+
|
48
|
+
def each(&block)
|
49
|
+
@pairs.each(&block)
|
50
|
+
end
|
51
|
+
|
52
|
+
def size()
|
53
|
+
@pairs.size
|
54
|
+
end
|
55
|
+
|
56
|
+
include Enumerable
|
57
|
+
})
|
58
|
+
|
59
|
+
def to_pairs(items, &block)
|
60
|
+
$rudebug::Pairs[*items.map { |item| [item, block.call(item)] }]
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_list(items)
|
64
|
+
to_pairs(0 .. items.size - 1) { |idx| items[idx] }
|
65
|
+
end
|
66
|
+
|
67
|
+
def inspect_obj(obj)
|
68
|
+
case obj
|
69
|
+
when UnboundMethod, Method then
|
70
|
+
inspect_method(obj)
|
71
|
+
else
|
72
|
+
#require 'pp'
|
73
|
+
#PP.pp(obj, "", 30).chomp
|
74
|
+
obj.inspect
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def inspect_method(method)
|
79
|
+
re = /^\x23<(?:Unbound)?Method: ([^(]+)(?:\\(([^)]+)\\))?\x23(.+?)>$/
|
80
|
+
if md = re.match(method.inspect) then
|
81
|
+
klass, diff_origin, name = *md.captures
|
82
|
+
origin = diff_origin || klass
|
83
|
+
argc = method.arity
|
84
|
+
more = argc < 0
|
85
|
+
argc = -argc if more
|
86
|
+
|
87
|
+
old_name = "a"
|
88
|
+
args = (1 .. argc).map do |idx|
|
89
|
+
arg_name = old_name.dup
|
90
|
+
old_name.succ!
|
91
|
+
arg_name
|
92
|
+
end
|
93
|
+
args[-1][0, 0] = "*" if more
|
94
|
+
|
95
|
+
"%s\x23%s(%s)" % [origin, name, args.join(", ")]
|
96
|
+
else
|
97
|
+
method.inspect
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
END_CODE
|
102
|
+
|
103
|
+
def self.load_rudebug_code(session)
|
104
|
+
session.eval(Code)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
eval(Connection::Base::Code)
|
@@ -1,109 +1,109 @@
|
|
1
|
-
require 'rudebug/connection/base'
|
2
|
-
|
3
|
-
class Connection::Breakpoint < Connection::Base
|
4
|
-
def stepping_support?()
|
5
|
-
false
|
6
|
-
end
|
7
|
-
|
8
|
-
class Session
|
9
|
-
attr_reader :title
|
10
|
-
|
11
|
-
def initialize(workspace, title = nil)
|
12
|
-
@workspace = workspace
|
13
|
-
@title = title
|
14
|
-
@done = false
|
15
|
-
|
16
|
-
Connection::Base.load_rudebug_code(self)
|
17
|
-
end
|
18
|
-
|
19
|
-
def eval(code)
|
20
|
-
@workspace.evaluate(nil, code).inspect
|
21
|
-
rescue Exception => e
|
22
|
-
raise(Connection::RemoteException, e.inspect)
|
23
|
-
end
|
24
|
-
|
25
|
-
def current_file()
|
26
|
-
Kernel.eval(eval("bp.file rescue @__bp_file"))
|
27
|
-
end
|
28
|
-
|
29
|
-
def current_line()
|
30
|
-
Kernel.eval(eval("bp.line rescue @__bp_line")).to_i
|
31
|
-
end
|
32
|
-
|
33
|
-
def source_code(file)
|
34
|
-
Kernel.eval(eval("File.read(%p)" % file)).chomp
|
35
|
-
end
|
36
|
-
|
37
|
-
def continue()
|
38
|
-
@done = true
|
39
|
-
return nil
|
40
|
-
end
|
41
|
-
|
42
|
-
def done?()
|
43
|
-
@done
|
44
|
-
end
|
45
|
-
|
46
|
-
# Safety
|
47
|
-
def step_into() end
|
48
|
-
def step_over() end
|
49
|
-
end
|
50
|
-
|
51
|
-
def connect(server)
|
52
|
-
require 'breakpoint'
|
53
|
-
require 'breakpoint/drb'
|
54
|
-
require 'drb'
|
55
|
-
|
56
|
-
DRb.start_service()
|
57
|
-
|
58
|
-
@service = DRbObject.new(nil, server)
|
59
|
-
@service.eval_handler = method(:eval_handler)
|
60
|
-
@service.handler = method(:breakpoint_handler)
|
61
|
-
|
62
|
-
@check_thread = Thread.new(
|
63
|
-
@service, @on_disconnect
|
64
|
-
) do |service, on_disconnect|
|
65
|
-
loop do
|
66
|
-
begin
|
67
|
-
service.ping
|
68
|
-
rescue DRb::DRbConnError => error
|
69
|
-
on_disconnect.call()
|
70
|
-
disconnect()
|
71
|
-
break
|
72
|
-
end
|
73
|
-
|
74
|
-
sleep(0.5)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def disconnect()
|
80
|
-
begin
|
81
|
-
@service.handler = nil
|
82
|
-
@service.eval_handler = nil
|
83
|
-
rescue Exception
|
84
|
-
end
|
85
|
-
|
86
|
-
@check_thread.kill if @check_thread
|
87
|
-
@check_thread = nil
|
88
|
-
|
89
|
-
DRb.stop_service()
|
90
|
-
@service = nil
|
91
|
-
end
|
92
|
-
|
93
|
-
def title_filter(message)
|
94
|
-
message[/"([^"]+)"/, 1] || message #"
|
95
|
-
end
|
96
|
-
|
97
|
-
def breakpoint_handler(workspace, message)
|
98
|
-
title = title_filter(message)
|
99
|
-
session = Session.new(workspace, title)
|
100
|
-
@on_session.call(session)
|
101
|
-
sleep 0.1 until session.done?
|
102
|
-
end
|
103
|
-
|
104
|
-
def eval_handler(code)
|
105
|
-
result = eval(code, TOPLEVEL_BINDING)
|
106
|
-
Breakpoint.undumpify(result)
|
107
|
-
return result
|
108
|
-
end
|
109
|
-
end
|
1
|
+
require 'rudebug/connection/base'
|
2
|
+
|
3
|
+
class Connection::Breakpoint < Connection::Base
|
4
|
+
def stepping_support?()
|
5
|
+
false
|
6
|
+
end
|
7
|
+
|
8
|
+
class Session
|
9
|
+
attr_reader :title
|
10
|
+
|
11
|
+
def initialize(workspace, title = nil)
|
12
|
+
@workspace = workspace
|
13
|
+
@title = title
|
14
|
+
@done = false
|
15
|
+
|
16
|
+
Connection::Base.load_rudebug_code(self)
|
17
|
+
end
|
18
|
+
|
19
|
+
def eval(code)
|
20
|
+
@workspace.evaluate(nil, code).inspect
|
21
|
+
rescue Exception => e
|
22
|
+
raise(Connection::RemoteException, e.inspect)
|
23
|
+
end
|
24
|
+
|
25
|
+
def current_file()
|
26
|
+
Kernel.eval(eval("bp.file rescue @__bp_file"))
|
27
|
+
end
|
28
|
+
|
29
|
+
def current_line()
|
30
|
+
Kernel.eval(eval("bp.line rescue @__bp_line")).to_i
|
31
|
+
end
|
32
|
+
|
33
|
+
def source_code(file)
|
34
|
+
Kernel.eval(eval("File.read(%p)" % file)).chomp
|
35
|
+
end
|
36
|
+
|
37
|
+
def continue()
|
38
|
+
@done = true
|
39
|
+
return nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def done?()
|
43
|
+
@done
|
44
|
+
end
|
45
|
+
|
46
|
+
# Safety
|
47
|
+
def step_into() end
|
48
|
+
def step_over() end
|
49
|
+
end
|
50
|
+
|
51
|
+
def connect(server)
|
52
|
+
require 'breakpoint'
|
53
|
+
require 'breakpoint/drb'
|
54
|
+
require 'drb'
|
55
|
+
|
56
|
+
DRb.start_service()
|
57
|
+
|
58
|
+
@service = DRbObject.new(nil, server)
|
59
|
+
@service.eval_handler = method(:eval_handler)
|
60
|
+
@service.handler = method(:breakpoint_handler)
|
61
|
+
|
62
|
+
@check_thread = Thread.new(
|
63
|
+
@service, @on_disconnect
|
64
|
+
) do |service, on_disconnect|
|
65
|
+
loop do
|
66
|
+
begin
|
67
|
+
service.ping
|
68
|
+
rescue DRb::DRbConnError => error
|
69
|
+
on_disconnect.call()
|
70
|
+
disconnect()
|
71
|
+
break
|
72
|
+
end
|
73
|
+
|
74
|
+
sleep(0.5)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def disconnect()
|
80
|
+
begin
|
81
|
+
@service.handler = nil
|
82
|
+
@service.eval_handler = nil
|
83
|
+
rescue Exception
|
84
|
+
end
|
85
|
+
|
86
|
+
@check_thread.kill if @check_thread
|
87
|
+
@check_thread = nil
|
88
|
+
|
89
|
+
DRb.stop_service()
|
90
|
+
@service = nil
|
91
|
+
end
|
92
|
+
|
93
|
+
def title_filter(message)
|
94
|
+
message[/"([^"]+)"/, 1] || message #"
|
95
|
+
end
|
96
|
+
|
97
|
+
def breakpoint_handler(workspace, message)
|
98
|
+
title = title_filter(message)
|
99
|
+
session = Session.new(workspace, title)
|
100
|
+
@on_session.call(session)
|
101
|
+
sleep 0.1 until session.done?
|
102
|
+
end
|
103
|
+
|
104
|
+
def eval_handler(code)
|
105
|
+
result = eval(code, TOPLEVEL_BINDING)
|
106
|
+
Breakpoint.undumpify(result)
|
107
|
+
return result
|
108
|
+
end
|
109
|
+
end
|
@@ -1,133 +1,133 @@
|
|
1
|
-
require 'rudebug/connection/base'
|
2
|
-
|
3
|
-
class Connection::RubyDebug < Connection::Base
|
4
|
-
def stepping_support?()
|
5
|
-
true
|
6
|
-
end
|
7
|
-
|
8
|
-
class Session
|
9
|
-
attr_reader :title
|
10
|
-
|
11
|
-
def initialize(connection, location)
|
12
|
-
@connection = connection
|
13
|
-
@location = location
|
14
|
-
@title = location.join(":")
|
15
|
-
@done = false
|
16
|
-
|
17
|
-
Connection::Base.load_rudebug_code(self)
|
18
|
-
end
|
19
|
-
|
20
|
-
def execute(cmd)
|
21
|
-
result = @connection.execute(cmd)
|
22
|
-
result ? result.chomp : result
|
23
|
-
end
|
24
|
-
|
25
|
-
def eval(code)
|
26
|
-
cmd = %(
|
27
|
-
p begin;
|
28
|
-
[eval(%p, nil, *([
|
29
|
-
caller[0].split(":")[0],
|
30
|
-
caller[0].split(":")[1].to_i
|
31
|
-
] rescue [])).inspect, nil];
|
32
|
-
rescue Exception;
|
33
|
-
[nil, $!.inspect];
|
34
|
-
end
|
35
|
-
).strip.gsub(/\n\s*/, "")
|
36
|
-
result, error = *Kernel.eval(execute(cmd % [code, @location]))
|
37
|
-
|
38
|
-
raise(Connection::RemoteException, error) if error
|
39
|
-
return result
|
40
|
-
end
|
41
|
-
|
42
|
-
def current_file()
|
43
|
-
@location[0]
|
44
|
-
end
|
45
|
-
|
46
|
-
def current_line()
|
47
|
-
@location[1].to_i
|
48
|
-
end
|
49
|
-
|
50
|
-
def source_code(file)
|
51
|
-
Kernel.eval(eval("File.read(%p)" % file)).chomp
|
52
|
-
end
|
53
|
-
|
54
|
-
def generic_step(cmd)
|
55
|
-
result = execute(cmd)
|
56
|
-
|
57
|
-
if result then
|
58
|
-
@connection.location?(result)
|
59
|
-
else
|
60
|
-
@connection.on_disconnect.call()
|
61
|
-
@connection.disconnect()
|
62
|
-
return nil
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def continue()
|
67
|
-
generic_step("cont")
|
68
|
-
end
|
69
|
-
|
70
|
-
def step_into()
|
71
|
-
generic_step("step")
|
72
|
-
end
|
73
|
-
|
74
|
-
def step_over()
|
75
|
-
generic_step("next")
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def connect(server)
|
80
|
-
require 'ruby-debug'
|
81
|
-
require 'socket'
|
82
|
-
require 'thread'
|
83
|
-
|
84
|
-
host, port = */^(.+):(\d+)$/.match(server).captures
|
85
|
-
port = port.to_i
|
86
|
-
|
87
|
-
@socket = TCPSocket.new(host, port)
|
88
|
-
line = @socket.gets
|
89
|
-
location = location?(line)
|
90
|
-
|
91
|
-
result = @socket.gets.strip rescue nil
|
92
|
-
if !prompt?(result) then
|
93
|
-
raise "Not a ruby-debug server"
|
94
|
-
end
|
95
|
-
|
96
|
-
@mutex = Mutex.new
|
97
|
-
|
98
|
-
session = Session.new(self, location)
|
99
|
-
@on_session.call(session)
|
100
|
-
end
|
101
|
-
|
102
|
-
def prompt?(line)
|
103
|
-
line[/^PROMPT /] rescue nil
|
104
|
-
end
|
105
|
-
|
106
|
-
def location?(line)
|
107
|
-
if md = /^(.+?):(\d+): /.match(line) then
|
108
|
-
file, line = *md.captures
|
109
|
-
[file, line.to_i]
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
def execute(cmd)
|
114
|
-
@mutex.synchronize do
|
115
|
-
@socket.puts(cmd)
|
116
|
-
result = @socket.gets
|
117
|
-
prompt = @socket.gets
|
118
|
-
|
119
|
-
#p result
|
120
|
-
#p [:prompt, prompt]
|
121
|
-
return result
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
def disconnect()
|
126
|
-
begin
|
127
|
-
@socket.close
|
128
|
-
rescue Exception
|
129
|
-
end
|
130
|
-
|
131
|
-
@socket = @mutex = nil
|
132
|
-
end
|
133
|
-
end
|
1
|
+
require 'rudebug/connection/base'
|
2
|
+
|
3
|
+
class Connection::RubyDebug < Connection::Base
|
4
|
+
def stepping_support?()
|
5
|
+
true
|
6
|
+
end
|
7
|
+
|
8
|
+
class Session
|
9
|
+
attr_reader :title
|
10
|
+
|
11
|
+
def initialize(connection, location)
|
12
|
+
@connection = connection
|
13
|
+
@location = location
|
14
|
+
@title = location.join(":")
|
15
|
+
@done = false
|
16
|
+
|
17
|
+
Connection::Base.load_rudebug_code(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
def execute(cmd)
|
21
|
+
result = @connection.execute(cmd)
|
22
|
+
result ? result.chomp : result
|
23
|
+
end
|
24
|
+
|
25
|
+
def eval(code)
|
26
|
+
cmd = %(
|
27
|
+
p begin;
|
28
|
+
[eval(%p, nil, *([
|
29
|
+
caller[0].split(":")[0],
|
30
|
+
caller[0].split(":")[1].to_i
|
31
|
+
] rescue [])).inspect, nil];
|
32
|
+
rescue Exception;
|
33
|
+
[nil, $!.inspect];
|
34
|
+
end
|
35
|
+
).strip.gsub(/\n\s*/, "")
|
36
|
+
result, error = *Kernel.eval(execute(cmd % [code, @location]))
|
37
|
+
|
38
|
+
raise(Connection::RemoteException, error) if error
|
39
|
+
return result
|
40
|
+
end
|
41
|
+
|
42
|
+
def current_file()
|
43
|
+
@location[0]
|
44
|
+
end
|
45
|
+
|
46
|
+
def current_line()
|
47
|
+
@location[1].to_i
|
48
|
+
end
|
49
|
+
|
50
|
+
def source_code(file)
|
51
|
+
Kernel.eval(eval("File.read(%p)" % file)).chomp
|
52
|
+
end
|
53
|
+
|
54
|
+
def generic_step(cmd)
|
55
|
+
result = execute(cmd)
|
56
|
+
|
57
|
+
if result then
|
58
|
+
@connection.location?(result)
|
59
|
+
else
|
60
|
+
@connection.on_disconnect.call()
|
61
|
+
@connection.disconnect()
|
62
|
+
return nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def continue()
|
67
|
+
generic_step("cont")
|
68
|
+
end
|
69
|
+
|
70
|
+
def step_into()
|
71
|
+
generic_step("step")
|
72
|
+
end
|
73
|
+
|
74
|
+
def step_over()
|
75
|
+
generic_step("next")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def connect(server)
|
80
|
+
require 'ruby-debug'
|
81
|
+
require 'socket'
|
82
|
+
require 'thread'
|
83
|
+
|
84
|
+
host, port = */^(.+):(\d+)$/.match(server).captures
|
85
|
+
port = port.to_i
|
86
|
+
|
87
|
+
@socket = TCPSocket.new(host, port)
|
88
|
+
line = @socket.gets
|
89
|
+
location = location?(line)
|
90
|
+
|
91
|
+
result = @socket.gets.strip rescue nil
|
92
|
+
if !prompt?(result) then
|
93
|
+
raise "Not a ruby-debug server"
|
94
|
+
end
|
95
|
+
|
96
|
+
@mutex = Mutex.new
|
97
|
+
|
98
|
+
session = Session.new(self, location)
|
99
|
+
@on_session.call(session)
|
100
|
+
end
|
101
|
+
|
102
|
+
def prompt?(line)
|
103
|
+
line[/^PROMPT /] rescue nil
|
104
|
+
end
|
105
|
+
|
106
|
+
def location?(line)
|
107
|
+
if md = /^(.+?):(\d+): /.match(line) then
|
108
|
+
file, line = *md.captures
|
109
|
+
[file, line.to_i]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def execute(cmd)
|
114
|
+
@mutex.synchronize do
|
115
|
+
@socket.puts(cmd)
|
116
|
+
result = @socket.gets
|
117
|
+
prompt = @socket.gets
|
118
|
+
|
119
|
+
#p result
|
120
|
+
#p [:prompt, prompt]
|
121
|
+
return result
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def disconnect()
|
126
|
+
begin
|
127
|
+
@socket.close
|
128
|
+
rescue Exception
|
129
|
+
end
|
130
|
+
|
131
|
+
@socket = @mutex = nil
|
132
|
+
end
|
133
|
+
end
|