ruby-debug 0.6.2 → 0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +8 -1
- data/bin/rdebug +5 -5
- data/ext/ruby_debug.c +377 -158
- data/lib/ruby-debug.rb +5 -7
- data/lib/ruby-debug/command.rb +29 -13
- data/lib/ruby-debug/commands/breakpoints.rb +1 -2
- data/lib/ruby-debug/commands/eval.rb +6 -9
- data/lib/ruby-debug/commands/frame.rb +16 -14
- data/lib/ruby-debug/commands/irb.rb +1 -5
- data/lib/ruby-debug/commands/list.rb +1 -9
- data/lib/ruby-debug/commands/settings.rb +41 -0
- data/lib/ruby-debug/commands/stepping.rb +2 -2
- data/lib/ruby-debug/commands/threads.rb +6 -8
- data/lib/ruby-debug/commands/tmate.rb +3 -4
- data/lib/ruby-debug/commands/variables.rb +10 -4
- data/lib/ruby-debug/processor.rb +12 -14
- metadata +15 -15
- data/ext/tags +0 -106
data/lib/ruby-debug.rb
CHANGED
@@ -259,10 +259,10 @@ module Debugger
|
|
259
259
|
end
|
260
260
|
|
261
261
|
def handle_post_mortem(exp)
|
262
|
-
return if exp.
|
262
|
+
return if exp.__debug_context.stack_size == 0
|
263
263
|
orig_tracing = Debugger.tracing, Debugger.current_context.tracing
|
264
264
|
Debugger.tracing = Debugger.current_context.tracing = false
|
265
|
-
processor.at_line(
|
265
|
+
processor.at_line(exp.__debug_context, exp.__debug_file, exp.__debug_line)
|
266
266
|
ensure
|
267
267
|
Debugger.tracing, Debugger.current_context.tracing = orig_tracing
|
268
268
|
end
|
@@ -271,7 +271,7 @@ module Debugger
|
|
271
271
|
end
|
272
272
|
|
273
273
|
class Exception # :nodoc:
|
274
|
-
attr_reader :__debug_file, :__debug_line, :__debug_binding, :
|
274
|
+
attr_reader :__debug_file, :__debug_line, :__debug_binding, :__debug_context
|
275
275
|
end
|
276
276
|
|
277
277
|
class DebugThread < Thread # :nodoc:
|
@@ -293,9 +293,7 @@ module Kernel
|
|
293
293
|
# Returns a binding of n-th call frame
|
294
294
|
#
|
295
295
|
def binding_n(n = 0)
|
296
|
-
|
297
|
-
raise "Unknown frame #{n}" unless frame
|
298
|
-
frame.binding
|
296
|
+
Debugger.current_context.frame_binding[n+1]
|
299
297
|
end
|
300
298
|
end
|
301
299
|
|
@@ -334,4 +332,4 @@ class Module
|
|
334
332
|
end
|
335
333
|
EOD
|
336
334
|
end
|
337
|
-
end
|
335
|
+
end
|
data/lib/ruby-debug/command.rb
CHANGED
@@ -43,6 +43,8 @@ module Debugger
|
|
43
43
|
@options ||= {}
|
44
44
|
end
|
45
45
|
end
|
46
|
+
|
47
|
+
@@display_stack_trace = false
|
46
48
|
|
47
49
|
def initialize(state)
|
48
50
|
@state = state
|
@@ -62,32 +64,46 @@ module Debugger
|
|
62
64
|
@state.confirm(msg) == 'y'
|
63
65
|
end
|
64
66
|
|
65
|
-
def debug_eval(str, b =
|
66
|
-
unless b
|
67
|
-
print "Can't evaluate in the current context.\nUse rdebug with -f option, or set Debugger.keep_frame_info = true.\n"
|
68
|
-
throw :debug_error
|
69
|
-
end
|
67
|
+
def debug_eval(str, b = get_binding)
|
70
68
|
begin
|
71
69
|
val = eval(str, b)
|
72
70
|
rescue StandardError, ScriptError => e
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
71
|
+
if @@display_stack_trace
|
72
|
+
at = eval("caller(1)", b)
|
73
|
+
print "%s:%s\n", at.shift, e.to_s.sub(/\(eval\):1:(in `.*?':)?/, '')
|
74
|
+
for i in at
|
75
|
+
print "\tfrom %s\n", i
|
76
|
+
end
|
77
|
+
else
|
78
|
+
print "Exception #{e.class}: #{e.message}\n"
|
79
|
+
end
|
78
80
|
throw :debug_error
|
79
81
|
end
|
80
82
|
end
|
81
83
|
|
82
84
|
def debug_silent_eval(str)
|
83
|
-
return nil unless @state.binding
|
84
85
|
begin
|
85
|
-
eval(str,
|
86
|
+
eval(str, get_binding)
|
86
87
|
rescue StandardError, ScriptError
|
87
88
|
nil
|
88
89
|
end
|
89
90
|
end
|
90
91
|
|
92
|
+
def hbinding(hash)
|
93
|
+
code = hash.keys.map{|k| "#{k} = hash['#{k}']"}.join(';') + ';binding'
|
94
|
+
if obj = @state.context.frame_self(@state.frame_pos)
|
95
|
+
obj.instance_eval code
|
96
|
+
else
|
97
|
+
eval code
|
98
|
+
end
|
99
|
+
end
|
100
|
+
private :hbinding
|
101
|
+
|
102
|
+
def get_binding
|
103
|
+
binding = @state.context.frame_binding(@state.frame_pos)
|
104
|
+
binding || hbinding(@state.context.frame_locals(@state.frame_pos))
|
105
|
+
end
|
106
|
+
|
91
107
|
def line_at(file, line)
|
92
108
|
Debugger.line_at(file, line)
|
93
109
|
end
|
@@ -98,4 +114,4 @@ module Debugger
|
|
98
114
|
end
|
99
115
|
|
100
116
|
Command.load_commands
|
101
|
-
end
|
117
|
+
end
|
@@ -1,22 +1,20 @@
|
|
1
1
|
module Debugger
|
2
2
|
class EvalCommand < Command # :nodoc:
|
3
|
+
self.control = true
|
4
|
+
|
3
5
|
def match(input)
|
4
6
|
@input = input
|
5
7
|
super
|
6
8
|
end
|
7
9
|
|
8
10
|
def regexp
|
9
|
-
/^\s*(p|e(?:val)?)
|
11
|
+
/^\s*(p|e(?:val)?)\s+/
|
10
12
|
end
|
11
13
|
|
12
14
|
def execute
|
13
|
-
if @match && @match[1] != 'p' && %w[on off].include?(@match[2])
|
14
|
-
self.class.unknown = @match[2] == 'on'
|
15
|
-
print "Evaluation of unknown command is #{self.class.unknown ? 'on': 'off'}.\n"
|
16
|
-
return
|
17
|
-
end
|
18
15
|
expr = @match ? @match.post_match : @input
|
19
|
-
|
16
|
+
binding = @state.context ? get_binding : TOPLEVEL_BINDING
|
17
|
+
print "%s\n", debug_eval(expr, binding).inspect
|
20
18
|
end
|
21
19
|
|
22
20
|
class << self
|
@@ -33,7 +31,6 @@ module Debugger
|
|
33
31
|
%{
|
34
32
|
e[val] expression\tevaluate expression and print its value,
|
35
33
|
\t\t\talias for p.
|
36
|
-
e[val] on/off\t\twhen 'on', debugger will evaluate every unknown command.
|
37
34
|
}
|
38
35
|
end
|
39
36
|
end
|
@@ -63,4 +60,4 @@ module Debugger
|
|
63
60
|
end
|
64
61
|
end
|
65
62
|
end
|
66
|
-
end
|
63
|
+
end
|
@@ -3,7 +3,7 @@ module Debugger
|
|
3
3
|
def adjust_frame(frame_pos, absolute)
|
4
4
|
if absolute
|
5
5
|
if frame_pos < 0
|
6
|
-
abs_frame_pos = @state.
|
6
|
+
abs_frame_pos = @state.context.stack_size + frame_pos
|
7
7
|
else
|
8
8
|
abs_frame_pos = frame_pos
|
9
9
|
end
|
@@ -11,7 +11,7 @@ module Debugger
|
|
11
11
|
abs_frame_pos = @state.frame_pos + frame_pos
|
12
12
|
end
|
13
13
|
|
14
|
-
if abs_frame_pos >= @state.
|
14
|
+
if abs_frame_pos >= @state.context.stack_size then
|
15
15
|
print "Adjusting would put us beyond the oldest (initial) frame.\n"
|
16
16
|
return
|
17
17
|
elsif abs_frame_pos < 0 then
|
@@ -22,9 +22,11 @@ module Debugger
|
|
22
22
|
@state.previous_line = nil
|
23
23
|
@state.frame_pos = abs_frame_pos
|
24
24
|
end
|
25
|
-
|
26
|
-
@state.
|
27
|
-
|
25
|
+
|
26
|
+
@state.file = @state.context.frame_file(@state.frame_pos)
|
27
|
+
@state.line = @state.context.frame_line(@state.frame_pos)
|
28
|
+
|
29
|
+
print format_frame(@state.frame_pos)
|
28
30
|
end
|
29
31
|
|
30
32
|
def get_int(str, cmd)
|
@@ -36,10 +38,10 @@ module Debugger
|
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
39
|
-
def format_frame(
|
41
|
+
def format_frame(pos)
|
40
42
|
printf "\032\032" if ENV['EMACS']
|
41
|
-
file, line, id =
|
42
|
-
"#%d %s:%s%s\n" % [pos
|
43
|
+
file, line, id = @state.context.frame_file(pos), @state.context.frame_line(pos), @state.context.frame_id(pos)
|
44
|
+
"#%d %s:%s%s\n" % [pos, file, line, (id ? ":in `#{id.id2name}'" : "")]
|
43
45
|
end
|
44
46
|
end
|
45
47
|
|
@@ -51,13 +53,13 @@ module Debugger
|
|
51
53
|
end
|
52
54
|
|
53
55
|
def execute
|
54
|
-
|
56
|
+
(0...@state.context.stack_size).each do |idx|
|
55
57
|
if idx == @state.frame_pos
|
56
58
|
print "--> "
|
57
59
|
else
|
58
60
|
print " "
|
59
61
|
end
|
60
|
-
print format_frame(
|
62
|
+
print format_frame(idx)
|
61
63
|
end
|
62
64
|
end
|
63
65
|
|
@@ -99,7 +101,7 @@ module Debugger
|
|
99
101
|
|
100
102
|
class << self
|
101
103
|
def help_command
|
102
|
-
up
|
104
|
+
'up'
|
103
105
|
end
|
104
106
|
|
105
107
|
def help(cmd)
|
@@ -114,7 +116,7 @@ module Debugger
|
|
114
116
|
include FrameFunctions
|
115
117
|
|
116
118
|
def regexp
|
117
|
-
/^\s* d(?:own)? (?:\s+(.*))? .*$/x
|
119
|
+
/^\s* d(?!isp)(?:own)? (?:\s+(.*))? .*$/x
|
118
120
|
end
|
119
121
|
|
120
122
|
def execute
|
@@ -154,7 +156,7 @@ module Debugger
|
|
154
156
|
pos = get_int(@match[1], "Frame")
|
155
157
|
return unless pos
|
156
158
|
end
|
157
|
-
adjust_frame(pos
|
159
|
+
adjust_frame(pos, true)
|
158
160
|
end
|
159
161
|
|
160
162
|
class << self
|
@@ -174,4 +176,4 @@ module Debugger
|
|
174
176
|
end
|
175
177
|
end
|
176
178
|
end
|
177
|
-
end
|
179
|
+
end
|
@@ -37,11 +37,7 @@ module Debugger
|
|
37
37
|
print "Command is available only in local mode.\n"
|
38
38
|
throw :debug_error
|
39
39
|
end
|
40
|
-
|
41
|
-
print "Can't evaluate in the current context.\n"
|
42
|
-
throw :debug_error
|
43
|
-
end
|
44
|
-
IRB.start_session(@state.binding)
|
40
|
+
IRB.start_session(get_binding)
|
45
41
|
end
|
46
42
|
|
47
43
|
class << self
|
@@ -15,14 +15,6 @@ module Debugger
|
|
15
15
|
@state.previous_line = nil
|
16
16
|
b = @state.line - 5
|
17
17
|
e = b + 9
|
18
|
-
elsif @match[2] == 'on'
|
19
|
-
self.class.always_run = true
|
20
|
-
print "Listing is on.\n"
|
21
|
-
return
|
22
|
-
elsif @match[2] == 'off'
|
23
|
-
self.class.always_run = false
|
24
|
-
print "Listing is off.\n"
|
25
|
-
return
|
26
18
|
else
|
27
19
|
b, e = @match[2].split(/[-,]/)
|
28
20
|
if e
|
@@ -110,4 +102,4 @@ module Debugger
|
|
110
102
|
end
|
111
103
|
end
|
112
104
|
end
|
113
|
-
end
|
105
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Debugger
|
2
|
+
class SetCommand < Command # :nodoc:
|
3
|
+
self.control = true
|
4
|
+
|
5
|
+
def regexp
|
6
|
+
/^set \s+ (.+) \s*/x
|
7
|
+
end
|
8
|
+
|
9
|
+
def execute
|
10
|
+
case @match[1]
|
11
|
+
when /^(no)?autolist$/
|
12
|
+
ListCommand.always_run = $1.nil?
|
13
|
+
print "Listing is #{$1.nil? ? 'on' : 'off'}.\n"
|
14
|
+
when /^(no)?autoeval$/
|
15
|
+
EvalCommand.unknown = $1.nil?
|
16
|
+
print "Evaluation of unrecognized command is #{$1.nil? ? 'on' : 'off'}.\n"
|
17
|
+
when /^(no)?trace$/
|
18
|
+
@@display_stack_trace = $1.nil?
|
19
|
+
print "Display stack trace is #{$1.nil? ? 'on' : 'off'}.\n"
|
20
|
+
else
|
21
|
+
print "Unknown setting.\n"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def help_command
|
27
|
+
"set"
|
28
|
+
end
|
29
|
+
|
30
|
+
def help(cmd)
|
31
|
+
%{
|
32
|
+
set <setting>, where <setting>:
|
33
|
+
autolist - execute 'list' command on every breakpoint
|
34
|
+
autoeval - evaluate every unrecognized command
|
35
|
+
trace - display stack trace when 'eval' raises exception
|
36
|
+
To disable setting, use 'no' prefix, like 'noautolist'
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -58,7 +58,7 @@ module Debugger
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def execute
|
61
|
-
if @state.frame_pos == @state.
|
61
|
+
if @state.frame_pos == @state.context.stack_size - 1
|
62
62
|
print "\"finish\" not meaningful in the outermost frame.\n"
|
63
63
|
else
|
64
64
|
@state.context.stop_frame = @state.frame_pos
|
@@ -101,4 +101,4 @@ module Debugger
|
|
101
101
|
end
|
102
102
|
end
|
103
103
|
end
|
104
|
-
end
|
104
|
+
end
|
@@ -2,13 +2,13 @@ module Debugger
|
|
2
2
|
module ThreadFunctions # :nodoc:
|
3
3
|
def display_context(c)
|
4
4
|
c_flag = c.thread == Thread.current ? '+' : ' '
|
5
|
+
c_flag = '$' if c.suspended?
|
5
6
|
d_flag = debugger_thread?(c) ? '!' : ' '
|
6
7
|
print "%s%s", c_flag, d_flag
|
7
8
|
print "%d ", c.thnum
|
8
9
|
print "%s\t", c.thread.inspect
|
9
|
-
|
10
|
-
|
11
|
-
print "%s:%d", last_frame.file, last_frame.line
|
10
|
+
if c.stack_size > 0
|
11
|
+
print "%s:%d", c.frame_file(0), c.frame_line(0)
|
12
12
|
end
|
13
13
|
print "\n"
|
14
14
|
end
|
@@ -100,11 +100,9 @@ module Debugger
|
|
100
100
|
print "It's the current thread.\n"
|
101
101
|
when debugger_thread?(c)
|
102
102
|
print "Can't stop the debugger thread.\n"
|
103
|
-
when c.thread.stop?
|
104
|
-
print "Already stopped.\n"
|
105
103
|
else
|
106
|
-
display_context(c)
|
107
104
|
c.suspend
|
105
|
+
display_context(c)
|
108
106
|
end
|
109
107
|
end
|
110
108
|
|
@@ -167,8 +165,8 @@ module Debugger
|
|
167
165
|
when !c.thread.stop?
|
168
166
|
print "Already running."
|
169
167
|
else
|
170
|
-
display_context(c)
|
171
168
|
c.resume
|
169
|
+
display_context(c)
|
172
170
|
end
|
173
171
|
end
|
174
172
|
|
@@ -184,4 +182,4 @@ module Debugger
|
|
184
182
|
end
|
185
183
|
end
|
186
184
|
end
|
187
|
-
end
|
185
|
+
end
|
@@ -8,12 +8,11 @@ module Debugger
|
|
8
8
|
def execute
|
9
9
|
if @match[1]
|
10
10
|
frm_n = @match[1].to_i
|
11
|
-
if frm_n > @state.
|
11
|
+
if frm_n > @state.context.stack_size || frm_n == 0
|
12
12
|
print "Wrong frame number\n"
|
13
13
|
return
|
14
14
|
end
|
15
|
-
|
16
|
-
file, line = frame.file, frame.line
|
15
|
+
file, line = @state.context.frame_file(frm_n-1), @state.context.frame_line(frm_n-1)
|
17
16
|
else
|
18
17
|
file, line = @state.file, @state.line
|
19
18
|
end
|
@@ -34,4 +33,4 @@ module Debugger
|
|
34
33
|
end
|
35
34
|
end
|
36
35
|
end
|
37
|
-
end
|
36
|
+
end
|
@@ -1,9 +1,15 @@
|
|
1
1
|
module Debugger
|
2
2
|
module VarFunctions # :nodoc:
|
3
|
-
def var_list(ary,
|
3
|
+
def var_list(ary, b = get_binding)
|
4
4
|
ary.sort!
|
5
5
|
for v in ary
|
6
|
-
print " %s => %s\n", v, debug_eval(v,
|
6
|
+
print " %s => %s\n", v, debug_eval(v, b).inspect
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def var_locals(locals)
|
11
|
+
locals.keys.sort.each do |name|
|
12
|
+
print " %s => %s\n", name, locals[name]
|
7
13
|
end
|
8
14
|
end
|
9
15
|
|
@@ -102,7 +108,7 @@ module Debugger
|
|
102
108
|
end
|
103
109
|
|
104
110
|
def execute
|
105
|
-
|
111
|
+
var_locals(@state.context.frame_locals(@state.frame_pos))
|
106
112
|
end
|
107
113
|
|
108
114
|
class << self
|
@@ -117,4 +123,4 @@ module Debugger
|
|
117
123
|
end
|
118
124
|
end
|
119
125
|
end
|
120
|
-
end
|
126
|
+
end
|