ruby-debug 0.10.1 → 0.10.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +7 -0
- data/ChangeLog +315 -278
- data/Rakefile +6 -6
- data/bin/rdebug +7 -3
- data/cli/ruby-debug.rb +2 -2
- data/cli/ruby-debug/commands/breakpoints.rb +15 -15
- data/cli/ruby-debug/commands/catchpoint.rb +18 -6
- data/cli/ruby-debug/commands/continue.rb +12 -6
- data/cli/ruby-debug/commands/info.rb +3 -3
- data/cli/ruby-debug/commands/irb.rb +2 -2
- data/cli/ruby-debug/commands/list.rb +1 -1
- data/cli/ruby-debug/commands/method.rb +44 -2
- data/cli/ruby-debug/commands/save.rb +16 -6
- data/cli/ruby-debug/commands/set.rb +11 -8
- data/cli/ruby-debug/commands/show.rb +28 -24
- data/cli/ruby-debug/commands/trace.rb +35 -11
- data/cli/ruby-debug/commands/variables.rb +47 -4
- data/cli/ruby-debug/interface.rb +28 -8
- data/cli/ruby-debug/processor.rb +6 -4
- data/rdbg.rb +0 -0
- data/test/base/base.rb +0 -0
- data/test/base/binding.rb +0 -0
- data/test/base/catchpoint.rb +0 -0
- data/test/bp_loop_issue.rb +3 -0
- data/test/classes.rb +11 -0
- data/test/cli/commands/catchpoint_test.rb +35 -0
- data/test/data/break_loop_bug.cmd +5 -0
- data/test/data/break_loop_bug.right +15 -0
- data/test/data/breakpoints.cmd +1 -1
- data/test/data/breakpoints.right +8 -12
- data/test/data/catch.cmd +17 -0
- data/test/data/catch.right +37 -0
- data/test/data/emacs_basic.right +2 -7
- data/test/data/frame.cmd +3 -0
- data/test/data/frame.right +4 -0
- data/test/data/method.cmd +10 -0
- data/test/data/method.right +21 -0
- data/test/data/methodsig.cmd +10 -0
- data/test/data/methodsig.right +20 -0
- data/test/data/output.right +0 -10
- data/test/data/quit.right +0 -9
- data/test/data/raise.right +1 -1
- data/test/data/save.cmd +33 -0
- data/test/data/save.right +59 -0
- data/test/data/setshow.cmd +13 -0
- data/test/data/setshow.right +25 -0
- data/test/dollar-0.rb +0 -0
- data/test/gcd-dbg.rb +0 -0
- data/test/helper.rb +24 -2
- data/test/pm-base.rb +0 -0
- data/test/pm.rb +0 -0
- data/test/raise.rb +0 -0
- data/test/tdebug.rb +5 -6
- data/test/test-annotate.rb +0 -0
- data/test/test-break-bad.rb +11 -0
- data/test/test-breakpoints.rb +0 -0
- data/test/test-catch.rb +25 -0
- data/test/test-condition.rb +0 -0
- data/test/test-ctrl.rb +0 -0
- data/test/test-display.rb +0 -0
- data/test/test-dollar-0.rb +0 -0
- data/test/test-edit.rb +0 -0
- data/test/test-emacs-basic.rb +2 -2
- data/test/test-enable.rb +0 -0
- data/test/test-finish.rb +0 -0
- data/test/test-frame.rb +11 -3
- data/test/test-help.rb +0 -0
- data/test/test-hist.rb +0 -0
- data/test/test-info-thread.rb +0 -0
- data/test/test-info-var.rb +0 -0
- data/test/test-info.rb +0 -0
- data/test/test-init.rb +3 -1
- data/test/test-list.rb +0 -0
- data/test/test-method.rb +34 -0
- data/test/test-output.rb +0 -0
- data/test/test-pm.rb +0 -0
- data/test/test-quit.rb +0 -0
- data/test/test-raise.rb +0 -0
- data/test/test-save.rb +25 -0
- data/test/test-setshow.rb +0 -0
- data/test/test-source.rb +0 -0
- data/test/test-stepping.rb +0 -0
- data/test/test-trace.rb +0 -0
- metadata +178 -155
- data/cli/ruby-debug/commands/disassemble.RB +0 -38
- data/test/except-bug2.rb +0 -7
data/Rakefile
CHANGED
@@ -20,7 +20,7 @@ COMMON_FILES = FileList[
|
|
20
20
|
'Rakefile',
|
21
21
|
]
|
22
22
|
|
23
|
-
CLI_TEST_FILE_LIST = 'test/test-*.rb'
|
23
|
+
CLI_TEST_FILE_LIST = FileList['test/test-*.rb', 'test/cli/**/*_test.rb']
|
24
24
|
CLI_FILES = COMMON_FILES + FileList[
|
25
25
|
"cli/**/*",
|
26
26
|
'ChangeLog',
|
@@ -30,7 +30,7 @@ CLI_FILES = COMMON_FILES + FileList[
|
|
30
30
|
'test/**/data/*.right',
|
31
31
|
'test/**/*.rb',
|
32
32
|
'rdbg.rb',
|
33
|
-
CLI_TEST_FILE_LIST
|
33
|
+
CLI_TEST_FILE_LIST
|
34
34
|
]
|
35
35
|
|
36
36
|
BASE_TEST_FILE_LIST = %w(
|
@@ -48,16 +48,16 @@ BASE_FILES = COMMON_FILES + FileList[
|
|
48
48
|
]
|
49
49
|
|
50
50
|
desc "Test everything."
|
51
|
-
|
51
|
+
task :test => :test_base do
|
52
52
|
Rake::TestTask.new(:test) do |t|
|
53
53
|
t.libs << ['./ext', './lib', './cli']
|
54
|
-
t.
|
54
|
+
t.test_files = CLI_TEST_FILE_LIST
|
55
55
|
t.verbose = true
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
59
|
desc "Test ruby-debug-base."
|
60
|
-
|
60
|
+
task :test_base => :lib do
|
61
61
|
Rake::TestTask.new(:test_base) do |t|
|
62
62
|
t.libs << ['./ext', './lib']
|
63
63
|
t.test_files = FileList[BASE_TEST_FILE_LIST]
|
@@ -198,7 +198,7 @@ task :publish do
|
|
198
198
|
# Get ruby-debug path.
|
199
199
|
ruby_debug_path = File.expand_path(File.dirname(__FILE__))
|
200
200
|
|
201
|
-
|
201
|
+
Rake::SshDirPublisher.new("kent@rubyforge.org",
|
202
202
|
"/var/www/gforge-projects/ruby-debug", ruby_debug_path)
|
203
203
|
end
|
204
204
|
|
data/bin/rdebug
CHANGED
@@ -38,9 +38,13 @@ def debug_program(options)
|
|
38
38
|
else
|
39
39
|
Debugger::PROG_SCRIPT
|
40
40
|
end
|
41
|
-
$0
|
41
|
+
if $0.frozen?
|
42
|
+
$0 = d0
|
43
|
+
else
|
44
|
+
$0[0..-1] = d0
|
45
|
+
end
|
42
46
|
end
|
43
|
-
bt = Debugger.debug_load(Debugger::PROG_SCRIPT, options.stop)
|
47
|
+
bt = Debugger.debug_load(Debugger::PROG_SCRIPT, options.stop, false)
|
44
48
|
if bt
|
45
49
|
if options.post_mortem
|
46
50
|
Debugger.handle_post_mortem(bt)
|
@@ -281,7 +285,7 @@ else
|
|
281
285
|
end
|
282
286
|
debug_program(options)
|
283
287
|
else
|
284
|
-
#
|
288
|
+
# Set up trace hook for debugger
|
285
289
|
Debugger.start
|
286
290
|
# start control thread
|
287
291
|
Debugger.start_control(options.host, options.cport) if options.control
|
data/cli/ruby-debug.rb
CHANGED
@@ -138,10 +138,10 @@ module Debugger
|
|
138
138
|
#
|
139
139
|
# Runs a script file
|
140
140
|
#
|
141
|
-
def run_script(file, out = handler.interface)
|
141
|
+
def run_script(file, out = handler.interface, verbose=false)
|
142
142
|
interface = ScriptInterface.new(File.expand_path(file), out)
|
143
143
|
processor = ControlCommandProcessor.new(interface)
|
144
|
-
processor.process_commands
|
144
|
+
processor.process_commands(verbose)
|
145
145
|
end
|
146
146
|
end
|
147
147
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module Debugger
|
2
|
-
|
2
|
+
|
3
|
+
# Implements debugger "break" command.
|
4
|
+
class AddBreakpoint < Command
|
3
5
|
self.allow_in_control = true
|
4
6
|
|
5
7
|
def regexp
|
@@ -60,19 +62,16 @@ module Debugger
|
|
60
62
|
|
61
63
|
if line =~ /^\d+$/
|
62
64
|
line = line.to_i
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
unless LineCache.trace_line_numbers(brkpt_filename).member?(line)
|
74
|
-
errmsg("Line %d is not a stopping point in file \"%s\".\n", line, file)
|
75
|
-
return
|
65
|
+
if LineCache.cache(brkpt_filename, Command.settings[:reload_source_on_change])
|
66
|
+
last_line = LineCache.size(brkpt_filename)
|
67
|
+
if line > last_line
|
68
|
+
errmsg("There are only %d lines in file \"%s\".\n", last_line, file)
|
69
|
+
return
|
70
|
+
end
|
71
|
+
unless LineCache.trace_line_numbers(brkpt_filename).member?(line)
|
72
|
+
errmsg("Line %d is not a stopping point in file \"%s\".\n", line, file)
|
73
|
+
return
|
74
|
+
end
|
76
75
|
end
|
77
76
|
unless @state.context
|
78
77
|
errmsg "We are not in a state we can add breakpoints.\n"
|
@@ -106,7 +105,8 @@ module Debugger
|
|
106
105
|
end
|
107
106
|
end
|
108
107
|
|
109
|
-
|
108
|
+
# Implements debugger "delete" command.
|
109
|
+
class DeleteBreakpointCommand < Command
|
110
110
|
self.allow_in_control = true
|
111
111
|
|
112
112
|
def regexp
|
@@ -3,14 +3,21 @@ module Debugger
|
|
3
3
|
self.allow_in_control = true
|
4
4
|
|
5
5
|
def regexp
|
6
|
-
/^\s* cat(?:ch)?
|
6
|
+
/^\s* cat(?:ch)?
|
7
|
+
(?:\s+ (\S+))?
|
8
|
+
(?:\s+ (off))? \s* $/ix
|
7
9
|
end
|
8
10
|
|
9
11
|
def execute
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
excn = @match[1]
|
13
|
+
if not excn
|
14
|
+
# No args given.
|
15
|
+
info_catch
|
16
|
+
elsif not @match[2]
|
17
|
+
# One arg given.
|
18
|
+
if 'off' == excn
|
19
|
+
Debugger.catchpoints.clear if
|
20
|
+
confirm("Delete all catchpoints? (y or n) ")
|
14
21
|
else
|
15
22
|
binding = @state.context ? get_binding : TOPLEVEL_BINDING
|
16
23
|
unless debug_eval("#{excn}.is_a?(Class)", binding)
|
@@ -19,8 +26,13 @@ module Debugger
|
|
19
26
|
Debugger.add_catchpoint(excn)
|
20
27
|
print "Catch exception %s.\n", excn
|
21
28
|
end
|
29
|
+
elsif @match[2] != 'off'
|
30
|
+
errmsg "Off expected. Got %s\n", @match[2]
|
31
|
+
elsif Debugger.catchpoints.member?(excn)
|
32
|
+
Debugger.catchpoints.delete(excn)
|
33
|
+
print "Catch for exception %s removed.\n", excn
|
22
34
|
else
|
23
|
-
|
35
|
+
errmsg "Catch for exception %s not found.\n", excn
|
24
36
|
end
|
25
37
|
end
|
26
38
|
|
@@ -1,18 +1,24 @@
|
|
1
1
|
module Debugger
|
2
|
+
|
2
3
|
# Implements debugger "continue" command.
|
3
4
|
class ContinueCommand < Command
|
4
|
-
self.allow_in_post_mortem =
|
5
|
-
self.need_context =
|
5
|
+
self.allow_in_post_mortem = true
|
6
|
+
self.need_context = false
|
6
7
|
def regexp
|
7
8
|
/^\s* c(?:ont(?:inue)?)? (?:\s+(.*))? $/x
|
8
9
|
end
|
9
10
|
|
10
11
|
def execute
|
11
12
|
if @match[1] && !@state.context.dead?
|
12
|
-
|
13
|
-
|
14
|
-
return unless
|
15
|
-
|
13
|
+
filename = File.expand_path(@state.file)
|
14
|
+
line_number = get_int(@match[1], "Continue", 0, nil, 0)
|
15
|
+
return unless line_number
|
16
|
+
unless LineCache.trace_line_numbers(filename).member?(line_number)
|
17
|
+
errmsg("Line %d is not a stopping point in file \"%s\".\n",
|
18
|
+
line_number, filename)
|
19
|
+
return
|
20
|
+
end
|
21
|
+
@state.context.set_breakpoint(filename, line_number)
|
16
22
|
end
|
17
23
|
@state.proceed
|
18
24
|
end
|
@@ -5,15 +5,15 @@ module Debugger
|
|
5
5
|
print "No frame selected.\n"
|
6
6
|
return
|
7
7
|
end
|
8
|
-
if Debugger.catchpoints.empty?
|
9
|
-
print "No exceptions set to be caught.\n"
|
10
|
-
else
|
8
|
+
if Debugger.catchpoints and not Debugger.catchpoints.empty?
|
11
9
|
# FIXME: show whether Exception is valid or not
|
12
10
|
# print "Exception: is_a?(Class)\n"
|
13
11
|
Debugger.catchpoints.each do |exception, hits|
|
14
12
|
# print "#{exception}: #{exception.is_a?(Class)}\n"
|
15
13
|
print "#{exception}\n"
|
16
14
|
end
|
15
|
+
else
|
16
|
+
print "No exceptions set to be caught.\n"
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -72,8 +72,8 @@ module Debugger
|
|
72
72
|
print "[%d, %d] in %s\n", b, e, file
|
73
73
|
lines = LineCache::getlines(file,
|
74
74
|
Command.settings[:reload_source_on_change])
|
75
|
-
return @state.previous_line if b >= lines.size
|
76
75
|
if lines
|
76
|
+
return @state.previous_line if b >= lines.size
|
77
77
|
e = lines.size if lines.size < e
|
78
78
|
[b, 1].max.upto(e) do |n|
|
79
79
|
if n > 0 && lines[n-1]
|
@@ -1,5 +1,46 @@
|
|
1
1
|
module Debugger
|
2
|
-
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'methodsig'
|
5
|
+
have_methodsig = true
|
6
|
+
rescue LoadError
|
7
|
+
have_methodsig = false
|
8
|
+
end
|
9
|
+
|
10
|
+
# Implements the debugger 'method sig' command.
|
11
|
+
class MethodSigCommand < Command
|
12
|
+
def regexp
|
13
|
+
/^\s*m(?:ethod)?\s+sig(?:nature)?\s+(\S+)\s*$/
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute
|
17
|
+
obj = debug_eval('method(:%s)' % @match[1])
|
18
|
+
if obj.is_a?(Method)
|
19
|
+
begin
|
20
|
+
print "%s\n", obj.signature.to_s
|
21
|
+
rescue
|
22
|
+
errmsg("Can't get signature for '#{@match[1]}'\n")
|
23
|
+
end
|
24
|
+
else
|
25
|
+
errmsg("Can't make method out of '#{@match[1]}'\n")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class << self
|
30
|
+
def help_command
|
31
|
+
'method'
|
32
|
+
end
|
33
|
+
|
34
|
+
def help(cmd)
|
35
|
+
%{
|
36
|
+
m[ethod] sig[nature] <obj>\tshow the signature of a method
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end if have_methodsig
|
41
|
+
|
42
|
+
# Implements the debugger 'method' command.
|
43
|
+
class MethodCommand < Command
|
3
44
|
def regexp
|
4
45
|
/^\s*m(?:ethod)?\s+((iv)|(i(:?nstance\s+)?)\s+)?/
|
5
46
|
end
|
@@ -33,10 +74,11 @@ module Debugger
|
|
33
74
|
def help(cmd)
|
34
75
|
%{
|
35
76
|
m[ethod] i[nstance] <obj>\tshow methods of object
|
36
|
-
m[ethod] iv <obj>\tshow instance variables of object
|
77
|
+
m[ethod] iv <obj>\t\tshow instance variables of object
|
37
78
|
m[ethod] <class|module>\t\tshow instance methods of class or module
|
38
79
|
}
|
39
80
|
end
|
40
81
|
end
|
41
82
|
end
|
83
|
+
|
42
84
|
end
|
@@ -20,7 +20,12 @@ module Debugger
|
|
20
20
|
Debugger.breakpoints.each do |b|
|
21
21
|
file.puts "break #{b.source}:#{b.pos}#{" if #{b.expr}" if b.expr}"
|
22
22
|
end
|
23
|
-
|
23
|
+
end
|
24
|
+
|
25
|
+
def save_catchpoints(file)
|
26
|
+
Debugger.catchpoints.keys.each do |c|
|
27
|
+
file.puts "catch #{c}"
|
28
|
+
end
|
24
29
|
end
|
25
30
|
|
26
31
|
def save_displays(file)
|
@@ -44,7 +49,9 @@ module Debugger
|
|
44
49
|
end
|
45
50
|
|
46
51
|
def regexp
|
47
|
-
/^\s*sa(?:ve)?
|
52
|
+
/^\s* sa(?:ve)?
|
53
|
+
(?:\s+(.+))?
|
54
|
+
\s*$/ix
|
48
55
|
end
|
49
56
|
|
50
57
|
def execute
|
@@ -54,6 +61,7 @@ module Debugger
|
|
54
61
|
file = open(@match[1], 'w')
|
55
62
|
end
|
56
63
|
save_breakpoints(file)
|
64
|
+
save_catchpoints(file)
|
57
65
|
# save_displays(file)
|
58
66
|
save_settings(file)
|
59
67
|
print "Saved to '#{file.path}'\n"
|
@@ -70,10 +78,12 @@ module Debugger
|
|
70
78
|
|
71
79
|
def help(cmd)
|
72
80
|
%{
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
81
|
+
save [FILE]
|
82
|
+
Saves current debugger state to FILE as a script file.
|
83
|
+
This includes breakpoints, catchpoints, display expressions and some settings.
|
84
|
+
If no filename is given, we will fabricate one.
|
85
|
+
|
86
|
+
Use the 'source' command in another debug session to restore them.}
|
77
87
|
end
|
78
88
|
end
|
79
89
|
end
|
@@ -110,15 +110,18 @@ set history size -- Set the size of the command history"],
|
|
110
110
|
when /^basename$/
|
111
111
|
Command.settings[:basename] = set_on
|
112
112
|
when /^callstyle$/
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
113
|
+
if args[0]
|
114
|
+
arg = args[0].downcase.to_sym
|
115
|
+
case arg
|
116
|
+
when :short, :last, :tracked
|
117
|
+
Command.settings[:callstyle] = arg
|
118
|
+
Debugger.track_frame_args = arg == :tracked ? true : false
|
119
|
+
print "%s\n" % show_setting(try_subcmd.name)
|
120
|
+
return
|
121
|
+
end
|
121
122
|
end
|
123
|
+
print "Invalid call style #{arg}. Should be one of: " +
|
124
|
+
"'short', 'last', or 'tracked'.\n"
|
122
125
|
when /^trace$/
|
123
126
|
Command.settings[:stack_trace_on_error] = set_on
|
124
127
|
when /^fullpath$/
|
@@ -38,33 +38,37 @@ module Debugger
|
|
38
38
|
style = Command.settings[:callstyle]
|
39
39
|
return "Frame call-display style is #{style}."
|
40
40
|
when /^commands(:?\s+(\d+))?$/
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
first_line
|
48
|
-
|
49
|
-
first_line
|
41
|
+
if @state.interface.readline_support?
|
42
|
+
s = '';
|
43
|
+
args = @match[1].split
|
44
|
+
if args[1]
|
45
|
+
first_line = args[1].to_i - 4
|
46
|
+
last_line = first_line + 10 - 1
|
47
|
+
if first_line > Readline::HISTORY.length
|
48
|
+
first_line = last_line = Readline::HISTORY.length
|
49
|
+
elsif first_line <= 0
|
50
|
+
first_line = 1
|
51
|
+
end
|
52
|
+
if last_line > Readline::HISTORY.length
|
53
|
+
last_line = Readline::HISTORY.length
|
54
|
+
end
|
55
|
+
i = first_line
|
56
|
+
commands = Readline::HISTORY.to_a[first_line..last_line]
|
57
|
+
else
|
58
|
+
if Readline::HISTORY.length > 10
|
59
|
+
commands = Readline::HISTORY.to_a[-10..-1]
|
60
|
+
i = Readline::HISTORY.length - 10
|
61
|
+
else
|
62
|
+
commands = Readline::HISTORY.to_a
|
63
|
+
i = 1
|
64
|
+
end
|
50
65
|
end
|
51
|
-
|
52
|
-
|
66
|
+
commands.each do |cmd|
|
67
|
+
s += ("%5d %s\n" % [i, cmd])
|
68
|
+
i += 1
|
53
69
|
end
|
54
|
-
i = first_line
|
55
|
-
commands = Readline::HISTORY.to_a[first_line..last_line]
|
56
70
|
else
|
57
|
-
|
58
|
-
commands = Readline::HISTORY.to_a[-10..-1]
|
59
|
-
i = Readline::HISTORY.length - 10
|
60
|
-
else
|
61
|
-
commands = Readline::HISTORY.to_a
|
62
|
-
i = 1
|
63
|
-
end
|
64
|
-
end
|
65
|
-
commands.each do |cmd|
|
66
|
-
s += ("%5d %s\n" % [i, cmd])
|
67
|
-
i += 1
|
71
|
+
s='No readline suport'
|
68
72
|
end
|
69
73
|
return s
|
70
74
|
when /^debuggertesting$/
|