ruby-debug 0.10.0 → 0.10.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/CHANGES +94 -2
- data/ChangeLog +5225 -0
- data/README +30 -1
- data/Rakefile +55 -24
- data/bin/rdebug +249 -128
- data/cli/ruby-debug/command.rb +30 -3
- data/cli/ruby-debug/commands/breakpoints.rb +54 -24
- data/cli/ruby-debug/commands/catchpoint.rb +13 -12
- data/cli/ruby-debug/commands/condition.rb +49 -0
- data/cli/ruby-debug/commands/continue.rb +32 -0
- data/cli/ruby-debug/commands/control.rb +19 -43
- data/cli/ruby-debug/commands/disassemble.RB +38 -0
- data/cli/ruby-debug/commands/display.rb +1 -1
- data/cli/ruby-debug/commands/edit.rb +48 -0
- data/cli/ruby-debug/commands/enable.rb +78 -35
- data/cli/ruby-debug/commands/eval.rb +6 -5
- data/cli/ruby-debug/commands/finish.rb +42 -0
- data/cli/ruby-debug/commands/frame.rb +64 -33
- data/cli/ruby-debug/commands/help.rb +19 -15
- data/cli/ruby-debug/commands/info.rb +295 -36
- data/cli/ruby-debug/commands/irb.rb +3 -1
- data/cli/ruby-debug/commands/list.rb +27 -50
- data/cli/ruby-debug/commands/quit.rb +38 -0
- data/cli/ruby-debug/commands/reload.rb +40 -0
- data/cli/ruby-debug/commands/save.rb +80 -0
- data/cli/ruby-debug/commands/{settings.rb → set.rb} +50 -12
- data/cli/ruby-debug/commands/show.rb +83 -27
- data/cli/ruby-debug/commands/source.rb +36 -0
- data/cli/ruby-debug/commands/stepping.rb +36 -72
- data/cli/ruby-debug/commands/threads.rb +32 -23
- data/cli/ruby-debug/commands/variables.rb +34 -4
- data/cli/ruby-debug/helper.rb +10 -75
- data/cli/ruby-debug/interface.rb +72 -9
- data/cli/ruby-debug/processor.rb +203 -100
- data/doc/rdebug.1 +7 -2
- data/rdbg.rb +33 -0
- data/test/{test-ruby-debug-base.rb → base/base.rb} +27 -29
- data/test/base/binding.rb +31 -0
- data/test/base/catchpoint.rb +26 -0
- data/test/base/load.rb +40 -0
- data/test/data/annotate.cmd +29 -0
- data/test/data/annotate.right +137 -0
- data/test/data/break_bad.cmd +18 -0
- data/test/data/break_bad.right +28 -0
- data/test/data/breakpoints.cmd +38 -0
- data/test/data/breakpoints.right +98 -0
- data/test/data/condition.cmd +28 -0
- data/test/data/condition.right +65 -0
- data/test/data/ctrl.cmd +23 -0
- data/test/data/ctrl.right +69 -0
- data/test/{display.cmd → data/display.cmd} +7 -1
- data/test/{display.right → data/display.right} +13 -6
- data/test/data/dollar-0.right +2 -0
- data/test/data/dollar-0a.right +2 -0
- data/test/data/dollar-0b.right +2 -0
- data/test/data/edit.cmd +12 -0
- data/test/data/edit.right +19 -0
- data/test/{breakpoints.cmd → data/emacs_basic.cmd} +0 -0
- data/test/{breakpoints.right → data/emacs_basic.right} +24 -12
- data/test/data/enable.cmd +20 -0
- data/test/data/enable.right +36 -0
- data/test/data/finish.cmd +16 -0
- data/test/data/finish.right +43 -0
- data/test/{frame.cmd → data/frame.cmd} +2 -0
- data/test/{frame.right → data/frame.right} +8 -2
- data/test/{help.cmd → data/help.cmd} +8 -0
- data/test/data/help.right +21 -0
- data/test/data/history.right +7 -0
- data/test/data/info-thread.cmd +13 -0
- data/test/data/info-thread.right +37 -0
- data/test/data/info-var-bug2.cmd +5 -0
- data/test/data/info-var-bug2.right +10 -0
- data/test/{info-var.cmd → data/info-var.cmd} +3 -3
- data/test/{info-var.right → data/info-var.right} +20 -15
- data/test/{info.cmd → data/info.cmd} +10 -1
- data/test/data/info.right +65 -0
- data/test/data/linetrace.cmd +6 -0
- data/test/data/linetrace.right +32 -0
- data/test/data/linetracep.cmd +7 -0
- data/test/data/linetracep.right +25 -0
- data/test/data/list.cmd +19 -0
- data/test/data/list.right +127 -0
- data/test/data/noquit.right +1 -0
- data/test/data/output.cmd +6 -0
- data/test/data/output.right +41 -0
- data/test/data/post-mortem-next.cmd +8 -0
- data/test/data/post-mortem-next.right +14 -0
- data/test/data/post-mortem-osx.right +31 -0
- data/test/data/post-mortem.cmd +13 -0
- data/test/data/post-mortem.right +31 -0
- data/test/{quit.cmd → data/quit.cmd} +2 -5
- data/test/data/quit.right +9 -0
- data/test/data/raise.cmd +11 -0
- data/test/data/raise.right +26 -0
- data/test/{setshow.cmd → data/setshow.cmd} +0 -1
- data/test/{setshow.right → data/setshow.right} +0 -1
- data/test/data/source.cmd +5 -0
- data/test/data/source.right +15 -0
- data/test/{stepping.cmd → data/stepping.cmd} +6 -2
- data/test/{stepping.right → data/stepping.right} +13 -3
- data/test/data/test-init-cygwin.right +7 -0
- data/test/data/test-init-osx.right +4 -0
- data/test/data/test-init.right +5 -0
- data/test/data/trace.right +23 -0
- data/test/dollar-0.rb +5 -0
- data/test/except-bug2.rb +7 -0
- data/test/gcd-dbg-nox.rb +31 -0
- data/test/gcd-dbg.rb +30 -0
- data/test/helper.rb +44 -14
- data/test/info-var-bug.rb +2 -0
- data/test/info-var-bug2.rb +2 -0
- data/test/null.rb +1 -0
- data/test/output.rb +2 -0
- data/test/pm-base.rb +22 -0
- data/test/pm.rb +11 -0
- data/test/raise.rb +3 -0
- data/test/tdebug.rb +88 -40
- data/test/test-annotate.rb +25 -0
- data/test/test-break-bad.rb +25 -0
- data/test/test-breakpoints.rb +14 -17
- data/test/test-condition.rb +25 -0
- data/test/test-ctrl.rb +54 -0
- data/test/test-display.rb +15 -15
- data/test/test-dollar-0.rb +39 -0
- data/test/test-edit.rb +26 -0
- data/test/test-emacs-basic.rb +26 -0
- data/test/test-enable.rb +25 -0
- data/test/test-finish.rb +34 -0
- data/test/test-frame.rb +15 -16
- data/test/test-help.rb +34 -18
- data/test/test-hist.rb +68 -0
- data/test/test-info-thread.rb +32 -0
- data/test/test-info-var.rb +28 -14
- data/test/test-info.rb +15 -17
- data/test/test-init.rb +41 -0
- data/test/test-list.rb +25 -0
- data/test/test-output.rb +26 -0
- data/test/test-pm.rb +46 -0
- data/test/test-quit.rb +19 -17
- data/test/test-raise.rb +25 -0
- data/test/test-setshow.rb +14 -13
- data/test/test-source.rb +25 -0
- data/test/test-stepping.rb +14 -14
- data/test/test-trace.rb +63 -0
- data/test/thread1.rb +26 -0
- metadata +125 -31
- data/cli/ruby-debug/commands/script.rb +0 -64
- data/runner.sh +0 -7
- data/test/help.right +0 -4
- data/test/info.right +0 -35
- data/test/quit.right +0 -22
- data/test/test-columnize.rb +0 -46
|
@@ -1,31 +1,35 @@
|
|
|
1
|
-
# Display a list of strings as a compact set of columns.
|
|
2
|
-
#
|
|
3
|
-
# Each column is only as wide as necessary.
|
|
4
|
-
# Columns are separated by two spaces (one was not legible enough).
|
|
5
|
-
# Adapted from the routine of the same name in cmd.py
|
|
6
|
-
|
|
7
1
|
module Debugger
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
|
|
3
|
+
# Implements debugger "help" command.
|
|
4
|
+
class HelpCommand < Command
|
|
5
|
+
self.allow_in_control = true
|
|
10
6
|
|
|
11
7
|
def regexp
|
|
12
|
-
/^\s*h(?:elp)?(?:\s+(.+))
|
|
8
|
+
/^\s* h(?:elp)? (?:\s+(.+))? $/x
|
|
13
9
|
end
|
|
14
10
|
|
|
15
11
|
def execute
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
if @match[1]
|
|
13
|
+
args = @match[1].split
|
|
14
|
+
cmds = @state.commands.select do |cmd|
|
|
15
|
+
[cmd.help_command].flatten.include?(args[0])
|
|
16
|
+
end
|
|
17
|
+
else
|
|
18
|
+
args = @match[1]
|
|
19
|
+
cmds = []
|
|
20
|
+
end
|
|
19
21
|
unless cmds.empty?
|
|
20
|
-
help = cmds.map{ |cmd| cmd.help(
|
|
22
|
+
help = cmds.map{ |cmd| cmd.help(args) }.join
|
|
21
23
|
help = help.split("\n").map{|l| l.gsub(/^ +/, '')}
|
|
22
24
|
help.shift if help.first && help.first.empty?
|
|
23
25
|
help.pop if help.last && help.last.empty?
|
|
24
26
|
print help.join("\n")
|
|
25
27
|
else
|
|
26
|
-
if
|
|
27
|
-
|
|
28
|
+
if args and args[0]
|
|
29
|
+
errmsg "Undefined command: \"#{args[0]}\". Try \"help\"."
|
|
28
30
|
else
|
|
31
|
+
print "ruby-debug help v#{Debugger::VERSION}\n" unless
|
|
32
|
+
self.class.settings[:debuggertesting]
|
|
29
33
|
print "Type 'help <command-name>' for help on a specific command\n\n"
|
|
30
34
|
print "Available commands:\n"
|
|
31
35
|
cmds = @state.commands.map{ |cmd| cmd.help_command }
|
|
@@ -1,51 +1,119 @@
|
|
|
1
1
|
module Debugger
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
module InfoFunctions # :nodoc:
|
|
3
|
+
def info_catch(*args)
|
|
4
|
+
unless @state.context
|
|
5
|
+
print "No frame selected.\n"
|
|
6
|
+
return
|
|
7
|
+
end
|
|
8
|
+
if Debugger.catchpoints.empty?
|
|
9
|
+
print "No exceptions set to be caught.\n"
|
|
10
|
+
else
|
|
11
|
+
# FIXME: show whether Exception is valid or not
|
|
12
|
+
# print "Exception: is_a?(Class)\n"
|
|
13
|
+
Debugger.catchpoints.each do |exception, hits|
|
|
14
|
+
# print "#{exception}: #{exception.is_a?(Class)}\n"
|
|
15
|
+
print "#{exception}\n"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Implements debugger "info" command.
|
|
22
|
+
class InfoCommand < Command
|
|
23
|
+
self.allow_in_control = true
|
|
5
24
|
Subcommands =
|
|
6
25
|
[
|
|
7
|
-
['args', 1,
|
|
8
|
-
['breakpoints', 1,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
['
|
|
12
|
-
['
|
|
13
|
-
['
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
26
|
+
['args', 1, 'Argument variables of current stack frame'],
|
|
27
|
+
['breakpoints', 1, 'Status of user-settable breakpoints',
|
|
28
|
+
'Without argument, list info about all breakpoints. With an
|
|
29
|
+
integer argument, list info on that breakpoint.'],
|
|
30
|
+
['catch', 3, 'Exceptions that can be caught in the current stack frame'],
|
|
31
|
+
['display', 2, 'Expressions to display when program stops'],
|
|
32
|
+
['file', 4, 'Info about a particular file read in',
|
|
33
|
+
'
|
|
34
|
+
After the file name is supplied, you can list file attributes that
|
|
35
|
+
you wish to see.
|
|
36
|
+
|
|
37
|
+
Attributes include: "all", "basic", "breakpoint", "lines", "mtime", "path"
|
|
38
|
+
and "sha1".'],
|
|
39
|
+
['files', 5, 'File names and timestamps of files read in'],
|
|
40
|
+
['global_variables', 2, 'Global variables'],
|
|
41
|
+
['instance_variables', 2,
|
|
42
|
+
'Instance variables of the current stack frame'],
|
|
43
|
+
['line', 2,
|
|
44
|
+
'Line number and file name of current position in source file'],
|
|
45
|
+
['locals', 2, 'Local variables of the current stack frame'],
|
|
46
|
+
['program', 2, 'Execution status of the program'],
|
|
47
|
+
['stack', 2, 'Backtrace of the stack'],
|
|
48
|
+
['thread', 6, 'List info about thread NUM', '
|
|
49
|
+
If no thread number is given, we list info for all threads. \'terse\' and \'verbose\'
|
|
50
|
+
options are possible. If terse, just give summary thread name information. See
|
|
51
|
+
"help info threads" for more detail about this summary information.
|
|
52
|
+
|
|
53
|
+
If \'verbose\' appended to the end of the command, then the entire
|
|
54
|
+
stack trace is given for each thread.'],
|
|
55
|
+
['threads', 7, 'information of currently-known threads', '
|
|
56
|
+
This information includes whether the thread is current (+), if it is
|
|
57
|
+
suspended ($), or ignored (!). The thread number and the top stack
|
|
58
|
+
item. If \'verbose\' is given then the entire stack frame is shown.'],
|
|
59
|
+
['variables', 1,
|
|
60
|
+
'Local and instance variables of the current stack frame']
|
|
61
|
+
].map do |name, min, short_help, long_help|
|
|
62
|
+
SubcmdStruct.new(name, min, short_help, long_help)
|
|
21
63
|
end unless defined?(Subcommands)
|
|
22
64
|
|
|
65
|
+
InfoFileSubcommands =
|
|
66
|
+
[
|
|
67
|
+
['all', 1,
|
|
68
|
+
'All file information available - breakpoints, lines, mtime, path, and sha1'],
|
|
69
|
+
['basic', 2,
|
|
70
|
+
'basic information - path, number of lines'],
|
|
71
|
+
['breakpoints', 2, 'Show trace line numbers',
|
|
72
|
+
'These are the line number where a breakpoint can be set.'],
|
|
73
|
+
['lines', 1, 'Show number of lines in the file'],
|
|
74
|
+
['mtime', 1, 'Show modification time of file'],
|
|
75
|
+
['path', 4, 'Show full file path name for file'],
|
|
76
|
+
['sha1', 1, 'Show SHA1 hash of contents of the file']
|
|
77
|
+
].map do |name, min, short_help, long_help|
|
|
78
|
+
SubcmdStruct.new(name, min, short_help, long_help)
|
|
79
|
+
end unless defined?(InfoFileSubcommands)
|
|
80
|
+
|
|
81
|
+
InfoThreadSubcommands =
|
|
82
|
+
[
|
|
83
|
+
['terse', 1, 'summary information'],
|
|
84
|
+
['verbose', 1, 'summary information and stack frame info'],
|
|
85
|
+
].map do |name, min, short_help, long_help|
|
|
86
|
+
SubcmdStruct.new(name, min, short_help, long_help)
|
|
87
|
+
end unless defined?(InfoThreadSubcommands)
|
|
88
|
+
|
|
23
89
|
def regexp
|
|
24
90
|
/^\s* i(?:nfo)? (?:\s+(.*))?$/ix
|
|
25
91
|
end
|
|
26
92
|
|
|
27
93
|
def execute
|
|
28
|
-
if
|
|
29
|
-
|
|
94
|
+
if @match[1].empty?
|
|
95
|
+
errmsg "\"info\" must be followed by the name of an info command:\n"
|
|
30
96
|
print "List of info subcommands:\n\n"
|
|
31
97
|
for subcmd in Subcommands do
|
|
32
98
|
print "info #{subcmd.name} -- #{subcmd.short_help}\n"
|
|
33
99
|
end
|
|
34
100
|
else
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
end
|
|
101
|
+
args = @match[1].split(/[ \t]+/)
|
|
102
|
+
param = args.shift
|
|
103
|
+
subcmd = find(Subcommands, param)
|
|
104
|
+
if subcmd
|
|
105
|
+
send("info_#{subcmd.name}", *args)
|
|
106
|
+
else
|
|
107
|
+
errmsg "Unknown info command #{param}\n"
|
|
43
108
|
end
|
|
44
|
-
print "Unknown info command #{subcmd}\n"
|
|
45
109
|
end
|
|
46
110
|
end
|
|
47
111
|
|
|
48
112
|
def info_args(*args)
|
|
113
|
+
unless @state.context
|
|
114
|
+
print "No frame selected.\n"
|
|
115
|
+
return
|
|
116
|
+
end
|
|
49
117
|
locals = @state.context.frame_locals(@state.frame_pos)
|
|
50
118
|
args = @state.context.frame_args(@state.frame_pos)
|
|
51
119
|
args.each do |name|
|
|
@@ -58,9 +126,22 @@ module Debugger
|
|
|
58
126
|
end
|
|
59
127
|
|
|
60
128
|
def info_breakpoints(*args)
|
|
129
|
+
unless @state.context
|
|
130
|
+
print "info breakpoints not available here.\n"
|
|
131
|
+
return
|
|
132
|
+
end
|
|
61
133
|
unless Debugger.breakpoints.empty?
|
|
134
|
+
brkpts = Debugger.breakpoints.sort_by{|b| b.id}
|
|
135
|
+
unless args.empty?
|
|
136
|
+
a = args.map{|a| a.to_i}
|
|
137
|
+
brkpts = brkpts.select{|b| a.member?(b.id)}
|
|
138
|
+
if brkpts.empty?
|
|
139
|
+
errmsg "No breakpoints found among list given.\n"
|
|
140
|
+
return
|
|
141
|
+
end
|
|
142
|
+
end
|
|
62
143
|
print "Num Enb What\n"
|
|
63
|
-
|
|
144
|
+
brkpts.each do |b|
|
|
64
145
|
if b.expr.nil?
|
|
65
146
|
print "%3d %s at %s:%s\n",
|
|
66
147
|
b.id, (b.enabled? ? 'y' : 'n'), b.source, b.pos
|
|
@@ -68,6 +149,11 @@ module Debugger
|
|
|
68
149
|
print "%3d %s at %s:%s if %s\n",
|
|
69
150
|
b.id, (b.enabled? ? 'y' : 'n'), b.source, b.pos, b.expr
|
|
70
151
|
end
|
|
152
|
+
hits = b.hit_count
|
|
153
|
+
if hits > 0
|
|
154
|
+
s = (hits > 1) ? 's' : ''
|
|
155
|
+
print "\tbreakpoint already hit #{hits} time#{s}\n"
|
|
156
|
+
end
|
|
71
157
|
end
|
|
72
158
|
else
|
|
73
159
|
print "No breakpoints.\n"
|
|
@@ -75,7 +161,11 @@ module Debugger
|
|
|
75
161
|
end
|
|
76
162
|
|
|
77
163
|
def info_display(*args)
|
|
78
|
-
|
|
164
|
+
unless @state.context
|
|
165
|
+
print "info display not available here.\n"
|
|
166
|
+
return
|
|
167
|
+
end
|
|
168
|
+
if @state.display.find{|d| d[0]}
|
|
79
169
|
print "Auto-display expressions now in effect:\n"
|
|
80
170
|
print "Num Enb Expression\n"
|
|
81
171
|
n = 1
|
|
@@ -90,21 +180,96 @@ module Debugger
|
|
|
90
180
|
end
|
|
91
181
|
|
|
92
182
|
def info_file(*args)
|
|
93
|
-
|
|
94
|
-
|
|
183
|
+
unless args[0]
|
|
184
|
+
info_files
|
|
185
|
+
return
|
|
186
|
+
end
|
|
187
|
+
file = args[0]
|
|
188
|
+
param = args[1]
|
|
189
|
+
|
|
190
|
+
param = 'basic' unless param
|
|
191
|
+
subcmd = find(InfoFileSubcommands, param)
|
|
192
|
+
unless subcmd
|
|
193
|
+
errmsg "Invalid parameter #{param}\n"
|
|
194
|
+
return
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
unless LineCache::cached?(file)
|
|
198
|
+
unless LineCache::cached_script?(file)
|
|
199
|
+
print "File #{file} is not cached\n"
|
|
200
|
+
return
|
|
201
|
+
end
|
|
202
|
+
LineCache::cache(file, Command.settings[:reload_source_on_change])
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
print "File %s", file
|
|
206
|
+
path = LineCache.path(file)
|
|
207
|
+
if %w(all basic path).member?(subcmd.name) and path != file
|
|
208
|
+
print " - %s\n", path
|
|
209
|
+
else
|
|
210
|
+
print "\n"
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
if %w(all basic lines).member?(subcmd.name)
|
|
214
|
+
lines = LineCache.size(file)
|
|
215
|
+
print "\t %d lines\n", lines if lines
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
if %w(all breakpoints).member?(subcmd.name)
|
|
219
|
+
breakpoints = LineCache.trace_line_numbers(file)
|
|
220
|
+
if breakpoints
|
|
221
|
+
print "\tbreakpoint line numbers:\n"
|
|
222
|
+
print columnize(breakpoints.to_a.sort, self.class.settings[:width])
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
if %w(all mtime).member?(subcmd.name)
|
|
227
|
+
stat = LineCache.stat(file)
|
|
228
|
+
print "\t%s\n", stat.mtime if stat
|
|
229
|
+
end
|
|
230
|
+
if %w(all sha1).member?(subcmd.name)
|
|
231
|
+
print "\t%s\n", LineCache.sha1(file)
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def info_files(*args)
|
|
236
|
+
files = LineCache::cached_files
|
|
237
|
+
files += SCRIPT_LINES__.keys unless 'stat' == args[0]
|
|
238
|
+
files.uniq.sort.each do |file|
|
|
239
|
+
stat = LineCache::stat(file)
|
|
240
|
+
path = LineCache::path(file)
|
|
241
|
+
print "File %s", file
|
|
242
|
+
if path and path != file
|
|
243
|
+
print " - %s\n", path
|
|
244
|
+
else
|
|
245
|
+
print "\n"
|
|
246
|
+
end
|
|
247
|
+
print "\t%s\n", stat.mtime if stat
|
|
95
248
|
end
|
|
96
249
|
end
|
|
97
250
|
|
|
98
251
|
def info_instance_variables(*args)
|
|
252
|
+
unless @state.context
|
|
253
|
+
print "info instance_variables not available here.\n"
|
|
254
|
+
return
|
|
255
|
+
end
|
|
99
256
|
obj = debug_eval('self')
|
|
100
257
|
var_list(obj.instance_variables)
|
|
101
258
|
end
|
|
102
259
|
|
|
103
260
|
def info_line(*args)
|
|
261
|
+
unless @state.context
|
|
262
|
+
errmsg "info line not available here.\n"
|
|
263
|
+
return
|
|
264
|
+
end
|
|
104
265
|
print "Line %d of \"%s\"\n", @state.line, @state.file
|
|
105
266
|
end
|
|
106
267
|
|
|
107
268
|
def info_locals(*args)
|
|
269
|
+
unless @state.context
|
|
270
|
+
errmsg "info line not available here.\n"
|
|
271
|
+
return
|
|
272
|
+
end
|
|
108
273
|
locals = @state.context.frame_locals(@state.frame_pos)
|
|
109
274
|
locals.keys.sort.each do |name|
|
|
110
275
|
### FIXME: make a common routine
|
|
@@ -125,10 +290,17 @@ module Debugger
|
|
|
125
290
|
end
|
|
126
291
|
|
|
127
292
|
def info_program(*args)
|
|
128
|
-
if @state.context
|
|
293
|
+
if not @state.context
|
|
129
294
|
print "The program being debugged is not being run.\n"
|
|
130
295
|
return
|
|
296
|
+
elsif @state.context.dead?
|
|
297
|
+
print "The program crashed.\n"
|
|
298
|
+
if Debugger.last_exception
|
|
299
|
+
print("Exception: #{Debugger.last_exception.inspect}\n")
|
|
300
|
+
end
|
|
301
|
+
return
|
|
131
302
|
end
|
|
303
|
+
|
|
132
304
|
print "Program stopped. "
|
|
133
305
|
case @state.context.stop_reason
|
|
134
306
|
when :step
|
|
@@ -145,6 +317,10 @@ module Debugger
|
|
|
145
317
|
end
|
|
146
318
|
|
|
147
319
|
def info_stack(*args)
|
|
320
|
+
if not @state.context
|
|
321
|
+
errmsg "info stack not available here.\n"
|
|
322
|
+
return
|
|
323
|
+
end
|
|
148
324
|
(0...@state.context.stack_size).each do |idx|
|
|
149
325
|
if idx == @state.frame_pos
|
|
150
326
|
print "--> "
|
|
@@ -154,20 +330,74 @@ module Debugger
|
|
|
154
330
|
print_frame(idx)
|
|
155
331
|
end
|
|
156
332
|
end
|
|
157
|
-
|
|
333
|
+
|
|
334
|
+
def info_thread_preamble(arg)
|
|
335
|
+
if not @state.context
|
|
336
|
+
errmsg "info threads not available here.\n"
|
|
337
|
+
return false, false
|
|
338
|
+
end
|
|
339
|
+
verbose = if arg
|
|
340
|
+
subcmd = find(InfoThreadSubcommands, arg)
|
|
341
|
+
unless subcmd
|
|
342
|
+
errmsg "'terse' or 'verbose' expected. Got '#{arg}'\n"
|
|
343
|
+
return false, false
|
|
344
|
+
end
|
|
345
|
+
'verbose' == subcmd.name
|
|
346
|
+
else
|
|
347
|
+
false
|
|
348
|
+
end
|
|
349
|
+
return true, verbose
|
|
350
|
+
end
|
|
351
|
+
private :info_thread_preamble
|
|
352
|
+
|
|
158
353
|
def info_threads(*args)
|
|
354
|
+
ok, verbose = info_thread_preamble(args[0])
|
|
355
|
+
return unless ok
|
|
159
356
|
threads = Debugger.contexts.sort_by{|c| c.thnum}.each do |c|
|
|
160
|
-
display_context(c)
|
|
357
|
+
display_context(c, !verbose)
|
|
358
|
+
if verbose and not c.ignored?
|
|
359
|
+
(0...c.stack_size).each do |idx|
|
|
360
|
+
print "\t"
|
|
361
|
+
print_frame(idx, false, c)
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
def info_thread(*args)
|
|
368
|
+
unless args[0]
|
|
369
|
+
info_threads(args[0])
|
|
370
|
+
return
|
|
371
|
+
end
|
|
372
|
+
ok, verbose = info_thread_preamble(args[1])
|
|
373
|
+
return unless ok
|
|
374
|
+
c = parse_thread_num("info thread" , args[0])
|
|
375
|
+
return unless c
|
|
376
|
+
display_context(c, !verbose)
|
|
377
|
+
if verbose and not c.ignored?
|
|
378
|
+
(0...c.stack_size).each do |idx|
|
|
379
|
+
print "\t"
|
|
380
|
+
print_frame(idx, false, c)
|
|
381
|
+
end
|
|
161
382
|
end
|
|
162
383
|
end
|
|
163
384
|
|
|
164
385
|
def info_global_variables(*args)
|
|
386
|
+
unless @state.context
|
|
387
|
+
errmsg "info global_variables not available here.\n"
|
|
388
|
+
return
|
|
389
|
+
end
|
|
165
390
|
var_list(global_variables)
|
|
166
391
|
end
|
|
167
392
|
|
|
168
393
|
def info_variables(*args)
|
|
394
|
+
if not @state.context
|
|
395
|
+
errmsg "info variables not available here.\n"
|
|
396
|
+
return
|
|
397
|
+
end
|
|
169
398
|
obj = debug_eval('self')
|
|
170
399
|
locals = @state.context.frame_locals(@state.frame_pos)
|
|
400
|
+
locals['self'] = @state.context.frame_self(@state.frame_pos)
|
|
171
401
|
locals.keys.sort.each do |name|
|
|
172
402
|
next if name =~ /^__dbg_/ # skip debugger pollution
|
|
173
403
|
### FIXME: make a common routine
|
|
@@ -183,9 +413,11 @@ module Debugger
|
|
|
183
413
|
if s.size > self.class.settings[:width]
|
|
184
414
|
s[self.class.settings[:width]-3 .. -1] = "..."
|
|
185
415
|
end
|
|
416
|
+
s.gsub!('%', '%%') # protect against printf format strings
|
|
186
417
|
print "#{s}\n"
|
|
187
418
|
end
|
|
188
419
|
var_list(obj.instance_variables, obj.instance_eval{binding()})
|
|
420
|
+
var_class_self
|
|
189
421
|
end
|
|
190
422
|
|
|
191
423
|
class << self
|
|
@@ -193,7 +425,34 @@ module Debugger
|
|
|
193
425
|
'info'
|
|
194
426
|
end
|
|
195
427
|
|
|
196
|
-
def help(
|
|
428
|
+
def help(args)
|
|
429
|
+
if args[1]
|
|
430
|
+
s = args[1]
|
|
431
|
+
subcmd = Subcommands.find do |try_subcmd|
|
|
432
|
+
(s.size >= try_subcmd.min) and
|
|
433
|
+
(try_subcmd.name[0..s.size-1] == s)
|
|
434
|
+
end
|
|
435
|
+
if subcmd
|
|
436
|
+
str = subcmd.short_help + '.'
|
|
437
|
+
if 'file' == subcmd.name and args[2]
|
|
438
|
+
s = args[2]
|
|
439
|
+
subsubcmd = InfoFileSubcommands.find do |try_subcmd|
|
|
440
|
+
(s.size >= try_subcmd.min) and
|
|
441
|
+
(try_subcmd.name[0..s.size-1] == s)
|
|
442
|
+
end
|
|
443
|
+
if subsubcmd
|
|
444
|
+
str += "\n" + subsubcmd.short_help + '.'
|
|
445
|
+
else
|
|
446
|
+
str += "\nInvalid file attribute #{args[2]}."
|
|
447
|
+
end
|
|
448
|
+
else
|
|
449
|
+
str += "\n" + subcmd.long_help if subcmd.long_help
|
|
450
|
+
end
|
|
451
|
+
return str
|
|
452
|
+
else
|
|
453
|
+
return "Invalid 'info' subcommand '#{args[1]}'."
|
|
454
|
+
end
|
|
455
|
+
end
|
|
197
456
|
s = %{
|
|
198
457
|
Generic command for showing things about the program being debugged.
|
|
199
458
|
--
|