rudebug 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|