trepanning 0.0.4
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/ChangeLog +4422 -0
- data/LICENSE +23 -0
- data/NEWS +12 -0
- data/README.textile +56 -0
- data/Rakefile +171 -0
- data/app/Makefile +7 -0
- data/app/breakpoint.rb +157 -0
- data/app/brkptmgr.rb +149 -0
- data/app/condition.rb +22 -0
- data/app/core.rb +203 -0
- data/app/default.rb +54 -0
- data/app/disassemble.rb +61 -0
- data/app/display.rb +148 -0
- data/app/file.rb +135 -0
- data/app/frame.rb +275 -0
- data/app/irb.rb +112 -0
- data/app/mock.rb +22 -0
- data/app/options.rb +122 -0
- data/app/run.rb +95 -0
- data/app/thread.rb +24 -0
- data/app/util.rb +32 -0
- data/bin/trepan +63 -0
- data/data/custom_require.rb +44 -0
- data/data/irbrc +55 -0
- data/data/prelude.rb +38 -0
- data/interface/base_intf.rb +95 -0
- data/interface/script.rb +103 -0
- data/interface/user.rb +90 -0
- data/io/base_io.rb +92 -0
- data/io/input.rb +111 -0
- data/io/string_array.rb +155 -0
- data/lib/Makefile +7 -0
- data/lib/trepanning.rb +277 -0
- data/processor/breakpoint.rb +108 -0
- data/processor/command/alias.rb +55 -0
- data/processor/command/backtrace.rb +95 -0
- data/processor/command/base/cmd.rb +97 -0
- data/processor/command/base/subcmd.rb +207 -0
- data/processor/command/base/submgr.rb +178 -0
- data/processor/command/base/subsubcmd.rb +102 -0
- data/processor/command/base/subsubmgr.rb +182 -0
- data/processor/command/break.rb +85 -0
- data/processor/command/condition.rb +64 -0
- data/processor/command/continue.rb +61 -0
- data/processor/command/debug.rb +85 -0
- data/processor/command/delete.rb +54 -0
- data/processor/command/directory.rb +43 -0
- data/processor/command/disable.rb +65 -0
- data/processor/command/disassemble.rb +103 -0
- data/processor/command/display.rb +81 -0
- data/processor/command/down.rb +56 -0
- data/processor/command/enable.rb +43 -0
- data/processor/command/exit.rb +54 -0
- data/processor/command/finish.rb +81 -0
- data/processor/command/frame.rb +117 -0
- data/processor/command/help.rb +146 -0
- data/processor/command/info.rb +28 -0
- data/processor/command/info_subcmd/args.rb +56 -0
- data/processor/command/info_subcmd/breakpoints.rb +162 -0
- data/processor/command/info_subcmd/file.rb +162 -0
- data/processor/command/info_subcmd/frame.rb +39 -0
- data/processor/command/info_subcmd/iseq.rb +83 -0
- data/processor/command/info_subcmd/locals.rb +88 -0
- data/processor/command/info_subcmd/program.rb +54 -0
- data/processor/command/info_subcmd/registers.rb +72 -0
- data/processor/command/info_subcmd/registers_subcmd/dfp.rb +38 -0
- data/processor/command/info_subcmd/registers_subcmd/helper.rb +40 -0
- data/processor/command/info_subcmd/registers_subcmd/lfp.rb +54 -0
- data/processor/command/info_subcmd/registers_subcmd/pc.rb +44 -0
- data/processor/command/info_subcmd/registers_subcmd/sp.rb +75 -0
- data/processor/command/info_subcmd/return.rb +40 -0
- data/processor/command/info_subcmd/thread.rb +106 -0
- data/processor/command/irb.rb +106 -0
- data/processor/command/kill.rb +58 -0
- data/processor/command/list.rb +327 -0
- data/processor/command/macro.rb +65 -0
- data/processor/command/next.rb +89 -0
- data/processor/command/nocache.rb +33 -0
- data/processor/command/print.rb +37 -0
- data/processor/command/ps.rb +40 -0
- data/processor/command/quit.rb +62 -0
- data/processor/command/raise.rb +47 -0
- data/processor/command/reload.rb +28 -0
- data/processor/command/reload_subcmd/command.rb +34 -0
- data/processor/command/restart.rb +57 -0
- data/processor/command/save.rb +60 -0
- data/processor/command/set.rb +47 -0
- data/processor/command/set_subcmd/auto.rb +27 -0
- data/processor/command/set_subcmd/auto_subcmd/eval.rb +67 -0
- data/processor/command/set_subcmd/auto_subcmd/irb.rb +49 -0
- data/processor/command/set_subcmd/auto_subcmd/list.rb +51 -0
- data/processor/command/set_subcmd/basename.rb +39 -0
- data/processor/command/set_subcmd/debug.rb +27 -0
- data/processor/command/set_subcmd/debug_subcmd/dbgr.rb +49 -0
- data/processor/command/set_subcmd/debug_subcmd/except.rb +35 -0
- data/processor/command/set_subcmd/debug_subcmd/macro.rb +35 -0
- data/processor/command/set_subcmd/debug_subcmd/skip.rb +35 -0
- data/processor/command/set_subcmd/debug_subcmd/stack.rb +45 -0
- data/processor/command/set_subcmd/different.rb +67 -0
- data/processor/command/set_subcmd/events.rb +71 -0
- data/processor/command/set_subcmd/max.rb +35 -0
- data/processor/command/set_subcmd/max_subcmd/list.rb +50 -0
- data/processor/command/set_subcmd/max_subcmd/stack.rb +60 -0
- data/processor/command/set_subcmd/max_subcmd/string.rb +53 -0
- data/processor/command/set_subcmd/max_subcmd/width.rb +50 -0
- data/processor/command/set_subcmd/return.rb +66 -0
- data/processor/command/set_subcmd/sp.rb +62 -0
- data/processor/command/set_subcmd/substitute.rb +25 -0
- data/processor/command/set_subcmd/substitute_subcmd/eval.rb +98 -0
- data/processor/command/set_subcmd/substitute_subcmd/path.rb +55 -0
- data/processor/command/set_subcmd/substitute_subcmd/string.rb +72 -0
- data/processor/command/set_subcmd/timer.rb +68 -0
- data/processor/command/set_subcmd/trace.rb +43 -0
- data/processor/command/set_subcmd/trace_subcmd/buffer.rb +56 -0
- data/processor/command/set_subcmd/trace_subcmd/print.rb +54 -0
- data/processor/command/set_subcmd/trace_subcmd/var.rb +61 -0
- data/processor/command/show.rb +27 -0
- data/processor/command/show_subcmd/alias.rb +50 -0
- data/processor/command/show_subcmd/args.rb +50 -0
- data/processor/command/show_subcmd/auto.rb +27 -0
- data/processor/command/show_subcmd/auto_subcmd/eval.rb +38 -0
- data/processor/command/show_subcmd/auto_subcmd/irb.rb +34 -0
- data/processor/command/show_subcmd/auto_subcmd/list.rb +36 -0
- data/processor/command/show_subcmd/basename.rb +28 -0
- data/processor/command/show_subcmd/debug.rb +27 -0
- data/processor/command/show_subcmd/debug_subcmd/dbgr.rb +31 -0
- data/processor/command/show_subcmd/debug_subcmd/except.rb +33 -0
- data/processor/command/show_subcmd/debug_subcmd/macro.rb +32 -0
- data/processor/command/show_subcmd/debug_subcmd/skip.rb +33 -0
- data/processor/command/show_subcmd/debug_subcmd/stack.rb +32 -0
- data/processor/command/show_subcmd/different.rb +37 -0
- data/processor/command/show_subcmd/events.rb +40 -0
- data/processor/command/show_subcmd/macro.rb +45 -0
- data/processor/command/show_subcmd/max.rb +31 -0
- data/processor/command/show_subcmd/max_subcmd/list.rb +39 -0
- data/processor/command/show_subcmd/max_subcmd/stack.rb +35 -0
- data/processor/command/show_subcmd/max_subcmd/string.rb +41 -0
- data/processor/command/show_subcmd/max_subcmd/width.rb +36 -0
- data/processor/command/show_subcmd/trace.rb +29 -0
- data/processor/command/show_subcmd/trace_subcmd/buffer.rb +84 -0
- data/processor/command/show_subcmd/trace_subcmd/print.rb +38 -0
- data/processor/command/source.rb +74 -0
- data/processor/command/step.rb +139 -0
- data/processor/command/stepi.rb +63 -0
- data/processor/command/unalias.rb +44 -0
- data/processor/command/undisplay.rb +63 -0
- data/processor/command/up.rb +92 -0
- data/processor/default.rb +45 -0
- data/processor/display.rb +17 -0
- data/processor/eval.rb +88 -0
- data/processor/eventbuf.rb +131 -0
- data/processor/frame.rb +230 -0
- data/processor/help.rb +72 -0
- data/processor/hook.rb +128 -0
- data/processor/load_cmds.rb +102 -0
- data/processor/location.rb +126 -0
- data/processor/main.rb +364 -0
- data/processor/mock.rb +100 -0
- data/processor/msg.rb +26 -0
- data/processor/running.rb +170 -0
- data/processor/subcmd.rb +159 -0
- data/processor/validate.rb +395 -0
- data/test/example/fname with blank.rb +1 -0
- data/test/example/gcd-xx.rb +18 -0
- data/test/example/gcd.rb +19 -0
- data/test/example/gcd1.rb +24 -0
- data/test/example/null.rb +1 -0
- data/test/example/thread1.rb +3 -0
- data/test/functional/fn_helper.rb +119 -0
- data/test/functional/test-break.rb +87 -0
- data/test/functional/test-condition.rb +59 -0
- data/test/functional/test-debugger-call-bug.rb +31 -0
- data/test/functional/test-delete.rb +71 -0
- data/test/functional/test-finish.rb +44 -0
- data/test/functional/test-immediate-step-bug.rb +35 -0
- data/test/functional/test-next.rb +77 -0
- data/test/functional/test-raise.rb +73 -0
- data/test/functional/test-return.rb +100 -0
- data/test/functional/test-step.rb +274 -0
- data/test/functional/test-stepbug.rb +40 -0
- data/test/functional/test-trace-var.rb +40 -0
- data/test/functional/tmp/b1.rb +5 -0
- data/test/functional/tmp/s1.rb +9 -0
- data/test/functional/tmp/t2.rb +6 -0
- data/test/integration/file-diff.rb +88 -0
- data/test/integration/helper.rb +52 -0
- data/test/integration/test-fname-with-blank.rb +11 -0
- data/test/integration/test-quit.rb +11 -0
- data/test/integration/try-test-enable.rb +11 -0
- data/test/unit/cmd-helper.rb +44 -0
- data/test/unit/test-app-brkpt.rb +30 -0
- data/test/unit/test-app-brkptmgr.rb +56 -0
- data/test/unit/test-app-disassemble.rb +60 -0
- data/test/unit/test-app-file.rb +46 -0
- data/test/unit/test-app-frame.rb +49 -0
- data/test/unit/test-app-options.rb +60 -0
- data/test/unit/test-app-run.rb +19 -0
- data/test/unit/test-app-thread.rb +25 -0
- data/test/unit/test-app-util.rb +17 -0
- data/test/unit/test-base-subcmd.rb +59 -0
- data/test/unit/test-bin-trepan.rb +48 -0
- data/test/unit/test-cmd-alias.rb +50 -0
- data/test/unit/test-cmd-break.rb +80 -0
- data/test/unit/test-cmd-endisable.rb +59 -0
- data/test/unit/test-cmd-help.rb +100 -0
- data/test/unit/test-cmd-kill.rb +47 -0
- data/test/unit/test-cmd-quit.rb +26 -0
- data/test/unit/test-cmd-step.rb +45 -0
- data/test/unit/test-intf-user.rb +45 -0
- data/test/unit/test-io-input.rb +26 -0
- data/test/unit/test-proc-eval.rb +26 -0
- data/test/unit/test-proc-frame.rb +77 -0
- data/test/unit/test-proc-help.rb +15 -0
- data/test/unit/test-proc-hook.rb +29 -0
- data/test/unit/test-proc-load_cmds.rb +40 -0
- data/test/unit/test-proc-main.rb +99 -0
- data/test/unit/test-proc-validate.rb +90 -0
- data/test/unit/test-subcmd-help.rb +48 -0
- metadata +358 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative 'base/submgr'
|
|
4
|
+
|
|
5
|
+
class Trepan::Command::InfoCommand < Trepan::SubcommandMgr
|
|
6
|
+
unless defined?(HELP)
|
|
7
|
+
HELP =
|
|
8
|
+
'Generic command for showing things about the program being debugged.
|
|
9
|
+
|
|
10
|
+
You can give unique prefix of the name of a subcommand to get
|
|
11
|
+
information about just that subcommand.
|
|
12
|
+
|
|
13
|
+
Type "info" for a list of "info" subcommands and what they do.
|
|
14
|
+
Type "help info *" for just a list of "info" subcommands.
|
|
15
|
+
'
|
|
16
|
+
|
|
17
|
+
ALIASES = %w(i)
|
|
18
|
+
CATEGORY = 'status'
|
|
19
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
20
|
+
SHORT_HELP = 'Information about debugged program and its environment'
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
if __FILE__ == $0
|
|
25
|
+
require_relative '../mock'
|
|
26
|
+
name = File.basename(__FILE__, '.rb')
|
|
27
|
+
dbgr, cmd = MockDebugger::setup(name)
|
|
28
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative '../base/subcmd'
|
|
4
|
+
require_relative '../../../app/frame'
|
|
5
|
+
|
|
6
|
+
class Trepan::Subcommand::InfoArgs < Trepan::Subcommand
|
|
7
|
+
unless defined?(HELP)
|
|
8
|
+
HELP = 'Show argument variables of the current stack frame'
|
|
9
|
+
MIN_ABBREV = 'ar'.size
|
|
10
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
11
|
+
NEED_STACK = true
|
|
12
|
+
PREFIX = %w(info args)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
include Trepan::Frame
|
|
16
|
+
def run(args)
|
|
17
|
+
if 'CFUNC' == @proc.frame.type
|
|
18
|
+
argc = @proc.frame.argc
|
|
19
|
+
if argc > 0
|
|
20
|
+
1.upto(argc).each do |i|
|
|
21
|
+
msg "#{i}: #{@proc.frame.sp(argc-i+3).inspect}"
|
|
22
|
+
end
|
|
23
|
+
else
|
|
24
|
+
msg("No parameters in C call.")
|
|
25
|
+
end
|
|
26
|
+
else
|
|
27
|
+
param_names = all_param_names(@proc.frame.iseq, false)
|
|
28
|
+
if param_names.empty?
|
|
29
|
+
msg("No parameters in call.")
|
|
30
|
+
else
|
|
31
|
+
param_names.each_with_index do |var_name, i|
|
|
32
|
+
var_value = @proc.safe_rep(@proc.debug_eval_no_errmsg(var_name).inspect)
|
|
33
|
+
msg("#{var_name} = #{var_value}")
|
|
34
|
+
end
|
|
35
|
+
unless 'call' == @proc.event and 0 == @proc.frame_index
|
|
36
|
+
msg("Values may have change from the initial call values.")
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
if __FILE__ == $0
|
|
44
|
+
# Demo it.
|
|
45
|
+
require_relative '../../mock'
|
|
46
|
+
require_relative '../../subcmd'
|
|
47
|
+
name = File.basename(__FILE__, '.rb')
|
|
48
|
+
|
|
49
|
+
# FIXME: DRY the below code
|
|
50
|
+
dbgr, cmd = MockDebugger::setup('info')
|
|
51
|
+
subcommand = Trepan::Subcommand::InfoArgs.new(cmd)
|
|
52
|
+
testcmdMgr = Trepan::Subcmd.new(subcommand)
|
|
53
|
+
|
|
54
|
+
name = File.basename(__FILE__, '.rb')
|
|
55
|
+
subcommand.summary_help(name)
|
|
56
|
+
end
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative '../base/subcmd'
|
|
4
|
+
|
|
5
|
+
class Trepan::Subcommand::InfoBreakpoints < Trepan::Subcommand
|
|
6
|
+
unless defined?(HELP)
|
|
7
|
+
HELP = <<EOH
|
|
8
|
+
info breakpoints [num1 ...] [verbose]
|
|
9
|
+
|
|
10
|
+
Show status of user-settable breakpoints. If no breakpoint numbers are
|
|
11
|
+
given, the show all breakpoints. Otherwise only those breakpoints
|
|
12
|
+
listed are shown and the order given. If VERBOSE is given, more
|
|
13
|
+
information provided about each breakpoint.
|
|
14
|
+
|
|
15
|
+
The "Disp" column contains one of "keep", "del", the disposition of
|
|
16
|
+
the breakpoint after it gets hit.
|
|
17
|
+
|
|
18
|
+
The "enb" column indicates whether the breakpoint is enabled.
|
|
19
|
+
|
|
20
|
+
The "Where" column indicates where the breakpoint is located.
|
|
21
|
+
EOH
|
|
22
|
+
|
|
23
|
+
MIN_ABBREV = 'br'.size
|
|
24
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
25
|
+
PREFIX = %w(info breakpoints)
|
|
26
|
+
SHORT_HELP = "Status of user-settable breakpoints"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def bpprint(bp, verbose=false)
|
|
30
|
+
disp = bp.temp? ? 'del ' : 'keep '
|
|
31
|
+
disp += bp.enabled? ? 'y ' : 'n '
|
|
32
|
+
|
|
33
|
+
iseq = bp.iseq
|
|
34
|
+
mess = '%-4dbreakpoint %s at ' % [bp.id, disp]
|
|
35
|
+
|
|
36
|
+
line_loc = '%s:%d' %
|
|
37
|
+
[iseq.source_container.join(' '),
|
|
38
|
+
iseq.offset2lines(bp.offset).join(', ')]
|
|
39
|
+
vm_loc = "VM offset %d of instruction sequence \"%s\"" %
|
|
40
|
+
[bp.offset, iseq.name]
|
|
41
|
+
|
|
42
|
+
loc, other_loc =
|
|
43
|
+
if 'line' == bp.type
|
|
44
|
+
[line_loc, vm_loc]
|
|
45
|
+
else # 'offset' == bp.type
|
|
46
|
+
[vm_loc, line_loc]
|
|
47
|
+
end
|
|
48
|
+
msg(mess + loc)
|
|
49
|
+
msg("\t#{other_loc}") if verbose
|
|
50
|
+
|
|
51
|
+
if bp.condition && bp.condition != 'true'
|
|
52
|
+
msg("\tstop only if %s" % bp.condition)
|
|
53
|
+
end
|
|
54
|
+
if bp.ignore > 0
|
|
55
|
+
msg("\tignore next %d hits" % bp.ignore)
|
|
56
|
+
end
|
|
57
|
+
if bp.hits > 0
|
|
58
|
+
ss = (bp.hits > 1) ? 's' : ''
|
|
59
|
+
msg("\tbreakpoint already hit %d time%s" %
|
|
60
|
+
[bp.hits, ss])
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def save_command
|
|
65
|
+
bpmgr = @proc.brkpts
|
|
66
|
+
bpmgr.list.inject([]) do |res, bp|
|
|
67
|
+
iseq = bp.iseq
|
|
68
|
+
next unless 'file' == iseq.source_container[0]
|
|
69
|
+
loc = iseq.source_container[1] + ':'
|
|
70
|
+
loc +=
|
|
71
|
+
# if 'line' == bp.type
|
|
72
|
+
iseq.offset2lines(bp.offset)[0].to_s
|
|
73
|
+
# else
|
|
74
|
+
# 'O' + bp.offset.to_s
|
|
75
|
+
# end
|
|
76
|
+
res << "break #{loc}"
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def run(args)
|
|
81
|
+
verbose = false
|
|
82
|
+
unless args.empty?
|
|
83
|
+
if 'verbose' == args[-1]
|
|
84
|
+
verbose = true
|
|
85
|
+
args.pop
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
show_all =
|
|
91
|
+
if args.size > 2
|
|
92
|
+
opts = {
|
|
93
|
+
:msg_on_error =>
|
|
94
|
+
"An '#{PREFIX.join(' ')}' argument must eval to a breakpoint between 1..#{@proc.brkpts.max}.",
|
|
95
|
+
:min_value => 1,
|
|
96
|
+
:max_value => @proc.brkpts.max
|
|
97
|
+
}
|
|
98
|
+
bp_nums = @proc.get_int_list(args[2..-1])
|
|
99
|
+
false
|
|
100
|
+
else
|
|
101
|
+
true
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
bpmgr = @proc.brkpts
|
|
105
|
+
if bpmgr.empty?
|
|
106
|
+
msg('No breakpoints.')
|
|
107
|
+
else
|
|
108
|
+
# There's at least one
|
|
109
|
+
msg("Num Type Disp Enb Where")
|
|
110
|
+
if show_all
|
|
111
|
+
bpmgr.list.each do |bp|
|
|
112
|
+
bpprint(bp, verbose)
|
|
113
|
+
end
|
|
114
|
+
else
|
|
115
|
+
notfound = []
|
|
116
|
+
bp_nums.each do |bp_num|
|
|
117
|
+
bp = @proc.brkpts[bp_num]
|
|
118
|
+
if bp
|
|
119
|
+
bpprint(bp, verbose)
|
|
120
|
+
else
|
|
121
|
+
notfound << bp_num
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
errmsg "No breakpoint number(s) #{not_found.join(' ')}." unless
|
|
125
|
+
notfound.empty?
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
if __FILE__ == $0
|
|
133
|
+
# Demo it.
|
|
134
|
+
require_relative '../../mock'
|
|
135
|
+
name = File.basename(__FILE__, '.rb')
|
|
136
|
+
dbgr, cmd = MockDebugger::setup('info')
|
|
137
|
+
subcommand = Trepan::Subcommand::InfoBreak.new(cmd)
|
|
138
|
+
|
|
139
|
+
puts '-' * 20
|
|
140
|
+
subcommand.run(%w(info break))
|
|
141
|
+
puts '-' * 20
|
|
142
|
+
subcommand.summary_help(name)
|
|
143
|
+
puts
|
|
144
|
+
puts '-' * 20
|
|
145
|
+
|
|
146
|
+
require 'thread_frame'
|
|
147
|
+
tf = RubyVM::ThreadFrame.current
|
|
148
|
+
pc_offset = tf.pc_offset
|
|
149
|
+
def foo
|
|
150
|
+
5
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
brk_cmd = dbgr.core.processor.commands['break']
|
|
154
|
+
brk_cmd.run(['break', "O#{pc_offset}"])
|
|
155
|
+
cmd.run(%w(info break))
|
|
156
|
+
puts '-' * 20
|
|
157
|
+
brk_cmd.run(['break', 'foo'])
|
|
158
|
+
subcommand.run(%w(info break))
|
|
159
|
+
puts '-' * 20
|
|
160
|
+
p subcommand.save_command
|
|
161
|
+
|
|
162
|
+
end
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require 'linecache'
|
|
4
|
+
require_relative '../base/subcmd'
|
|
5
|
+
require_relative '../../../app/file'
|
|
6
|
+
|
|
7
|
+
class Trepan::Subcommand::InfoFile < Trepan::Subcommand
|
|
8
|
+
unless defined?(HELP)
|
|
9
|
+
DEFAULT_FILE_ARGS = %w(size sha1)
|
|
10
|
+
|
|
11
|
+
HELP =
|
|
12
|
+
"info file [{FILENAME|.} [all | brkpts | iseq | sha1 | size | stat]]
|
|
13
|
+
|
|
14
|
+
Show information about the current file. If no filename is given and
|
|
15
|
+
the program is running then the current file associated with the
|
|
16
|
+
current stack entry is used. Sub options which can be shown about a file are:
|
|
17
|
+
|
|
18
|
+
brkpts -- Line numbers where there are statement boundaries.
|
|
19
|
+
These lines can be used in breakpoint commands.
|
|
20
|
+
iseq -- Instruction sequences from this file.
|
|
21
|
+
sha1 -- A SHA1 hash of the source text. This may be useful in comparing
|
|
22
|
+
source code.
|
|
23
|
+
size -- The number of lines in the file.
|
|
24
|
+
stat -- File.stat information
|
|
25
|
+
|
|
26
|
+
all -- All of the above information.
|
|
27
|
+
|
|
28
|
+
If no sub-options are given #{DEFAULT_FILE_ARGS.join(' ')} are assumed.
|
|
29
|
+
"
|
|
30
|
+
MIN_ABBREV = 'fi'.size # Note we have "info frame"
|
|
31
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
32
|
+
NEED_STACK = false
|
|
33
|
+
PREFIX = %w(info file)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
include Trepanning
|
|
37
|
+
|
|
38
|
+
# Get file information
|
|
39
|
+
def run(args)
|
|
40
|
+
return if args.size < 2
|
|
41
|
+
args << '.' if 2 == args.size
|
|
42
|
+
filename =
|
|
43
|
+
if '.' == args[2]
|
|
44
|
+
if not @proc.frame
|
|
45
|
+
errmsg("No frame - no default file.")
|
|
46
|
+
return false
|
|
47
|
+
nil
|
|
48
|
+
else
|
|
49
|
+
File.expand_path(@proc.frame.source_container[1])
|
|
50
|
+
end
|
|
51
|
+
else
|
|
52
|
+
args[2]
|
|
53
|
+
end
|
|
54
|
+
args += DEFAULT_FILE_ARGS if args.size == 3
|
|
55
|
+
|
|
56
|
+
m = filename + ' is'
|
|
57
|
+
canonic_name = LineCache::map_file(filename)
|
|
58
|
+
if LineCache::cached?(canonic_name)
|
|
59
|
+
m += " cached in debugger"
|
|
60
|
+
if canonic_name != filename
|
|
61
|
+
m += (' as:' + canonic_name)
|
|
62
|
+
end
|
|
63
|
+
m += '.'
|
|
64
|
+
msg(m)
|
|
65
|
+
elsif !(matches = find_scripts(filename)).empty?
|
|
66
|
+
if (matches.size > 1)
|
|
67
|
+
msg("Multiple files found:")
|
|
68
|
+
matches.each { |filename| msg("\t%s" % filename) }
|
|
69
|
+
return
|
|
70
|
+
else
|
|
71
|
+
msg('File "%s" just now cached.' % filename)
|
|
72
|
+
LineCache::cache(matches[0])
|
|
73
|
+
LineCache::remap_file(matches[0], filename)
|
|
74
|
+
canonic_name = matches[0]
|
|
75
|
+
end
|
|
76
|
+
else
|
|
77
|
+
msg(m + ' not cached in debugger.')
|
|
78
|
+
return
|
|
79
|
+
end
|
|
80
|
+
seen = {}
|
|
81
|
+
args[3..-1].each do |arg|
|
|
82
|
+
processed_arg = false
|
|
83
|
+
|
|
84
|
+
if %w(all size).member?(arg)
|
|
85
|
+
unless seen[:size]
|
|
86
|
+
max_line = LineCache::size(canonic_name)
|
|
87
|
+
msg "File has %d lines." % max_line if max_line
|
|
88
|
+
end
|
|
89
|
+
processed_arg = seen[:size] = true
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
if %w(all sha1).member?(arg)
|
|
93
|
+
unless seen[:sha1]
|
|
94
|
+
msg("SHA1 is %s." % LineCache::sha1(canonic_name))
|
|
95
|
+
end
|
|
96
|
+
processed_arg = seen[:sha1] = true
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
if %w(all brkpts).member?(arg)
|
|
100
|
+
unless seen[:brkpts]
|
|
101
|
+
msg("Possible breakpoint line numbers:")
|
|
102
|
+
lines = LineCache::trace_line_numbers(canonic_name)
|
|
103
|
+
fmt_lines = columnize_numbers(lines)
|
|
104
|
+
msg(fmt_lines)
|
|
105
|
+
end
|
|
106
|
+
processed_arg = seen[:brkpts] = true
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
if %w(all iseq).member?(arg)
|
|
110
|
+
unless seen[:iseq]
|
|
111
|
+
if SCRIPT_ISEQS__.member?(canonic_name)
|
|
112
|
+
msg("File contains instruction sequences:")
|
|
113
|
+
SCRIPT_ISEQS__[canonic_name].each do |iseq|
|
|
114
|
+
msg("\t %s %s" % [iseq, iseq.name.inspect])
|
|
115
|
+
end
|
|
116
|
+
else
|
|
117
|
+
msg("Instruction sequences not recorded; there may be some, though.")
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
processed_arg = seen[:iseq] = true
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
if %w(all stat).member?(arg)
|
|
124
|
+
unless seen[:stat]
|
|
125
|
+
msg("Stat info:\n\t%s." % LineCache::stat(canonic_name).inspect)
|
|
126
|
+
end
|
|
127
|
+
processed_arg = seen[:stat] = true
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
if not processed_arg
|
|
131
|
+
errmsg("I don't understand sub-option \"%s\"." % arg)
|
|
132
|
+
end
|
|
133
|
+
end unless args.empty?
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
if __FILE__ == $0
|
|
138
|
+
if not (ARGV.size == 1 && ARGV[0] == 'noload')
|
|
139
|
+
ISEQS__ = {}
|
|
140
|
+
SCRIPT_ISEQS__ = {}
|
|
141
|
+
ARGV[0..-1] = ['noload']
|
|
142
|
+
load(__FILE__)
|
|
143
|
+
else
|
|
144
|
+
require_relative '../../mock'
|
|
145
|
+
require_relative '../../subcmd'
|
|
146
|
+
name = File.basename(__FILE__, '.rb')
|
|
147
|
+
# FIXME: DRY the below code
|
|
148
|
+
dbgr, cmd = MockDebugger::setup('info')
|
|
149
|
+
subcommand = Trepan::Subcommand::InfoFile.new(cmd)
|
|
150
|
+
testcmdMgr = Trepan::Subcmd.new(subcommand)
|
|
151
|
+
|
|
152
|
+
[%w(info file nothere),
|
|
153
|
+
%w(info file .),
|
|
154
|
+
%w(info file),
|
|
155
|
+
%w(info file file.rb),
|
|
156
|
+
%w(info file . all),
|
|
157
|
+
%w(info file . lines size sha1 sha1)].each do |args|
|
|
158
|
+
subcommand.run(args)
|
|
159
|
+
puts '-' * 40
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative '../base/subcmd'
|
|
4
|
+
|
|
5
|
+
class Trepan::Subcommand::InfoFrame < Trepan::Subcommand
|
|
6
|
+
unless defined?(HELP)
|
|
7
|
+
HELP = 'Show all information about the selected frame'
|
|
8
|
+
MIN_ABBREV = 'fr'.size # Note we have "info file"
|
|
9
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
10
|
+
NEED_STACK = true
|
|
11
|
+
PREFIX = %w(info frame)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def run(args)
|
|
15
|
+
frame = @proc.frame
|
|
16
|
+
msg("Line %s of %s at PC offset %d, type: %s" %
|
|
17
|
+
[@proc.frame_line, frame.source_container[1], frame.pc_offset,
|
|
18
|
+
frame.type])
|
|
19
|
+
if @proc.event == 'return'
|
|
20
|
+
msg("Return value class: #{@proc.frame.sp(1).class}")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if __FILE__ == $0
|
|
27
|
+
# Demo it.
|
|
28
|
+
require_relative '../../mock'
|
|
29
|
+
require_relative '../../subcmd'
|
|
30
|
+
name = File.basename(__FILE__, '.rb')
|
|
31
|
+
|
|
32
|
+
# FIXME: DRY the below code
|
|
33
|
+
dbgr, cmd = MockDebugger::setup('info')
|
|
34
|
+
subcommand = Trepan::Subcommand::InfoFrame.new(cmd)
|
|
35
|
+
testcmdMgr = Trepan::Subcmd.new(subcommand)
|
|
36
|
+
|
|
37
|
+
name = File.basename(__FILE__, '.rb')
|
|
38
|
+
subcommand.summary_help(name)
|
|
39
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative '../base/subcmd'
|
|
4
|
+
|
|
5
|
+
class Trepan::Subcommand::InfoIseq < Trepan::Subcommand
|
|
6
|
+
unless defined?(HELP)
|
|
7
|
+
HELP =
|
|
8
|
+
'info iseq [METHOD|.]
|
|
9
|
+
|
|
10
|
+
Show information about an instruction sequence.
|
|
11
|
+
|
|
12
|
+
Examples:
|
|
13
|
+
info iseq
|
|
14
|
+
info iseq .
|
|
15
|
+
info iseq require_relative
|
|
16
|
+
'
|
|
17
|
+
MIN_ABBREV = 'is'.size
|
|
18
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
19
|
+
NEED_STACK = true
|
|
20
|
+
PREFIX = %w(info iseq)
|
|
21
|
+
SHORT_HELP = 'Information about an instruction sequence'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def run(args)
|
|
25
|
+
if 2 == args.size
|
|
26
|
+
iseq_name = '.'
|
|
27
|
+
else
|
|
28
|
+
iseq_name = args[2]
|
|
29
|
+
end
|
|
30
|
+
if '.' == iseq_name
|
|
31
|
+
iseq = frame = @proc.frame.iseq
|
|
32
|
+
elsif !(matches = find_iseqs(ISEQS__, iseq_name)).empty?
|
|
33
|
+
# FIXME: do something if there is more than one
|
|
34
|
+
iseq = matches[0]
|
|
35
|
+
else
|
|
36
|
+
iseq = nil
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
if iseq
|
|
40
|
+
msg('Instruction sequence:')
|
|
41
|
+
%w(name source_container arg_block arg_opts arg_post_len arg_rest
|
|
42
|
+
arg_simple argc arity iseq_size local_size orig
|
|
43
|
+
).each do |field|
|
|
44
|
+
msg("\t#{field}: %s" % iseq.send(field).inspect)
|
|
45
|
+
end
|
|
46
|
+
msg("\tsha1: #{iseq.sha1}")
|
|
47
|
+
if iseq.brkpts
|
|
48
|
+
if iseq.brkpts.empty?
|
|
49
|
+
msg("Breakpoints have been allocated, but none have been set.")
|
|
50
|
+
else
|
|
51
|
+
s = iseq.brkpts.size > 1 ? 's' : ''
|
|
52
|
+
msg("Breakpoint%s at offset%s: %s" % [s, s, iseq.brkpts.join(', ')])
|
|
53
|
+
end
|
|
54
|
+
else
|
|
55
|
+
msg("Breakpoints have not been allocated.")
|
|
56
|
+
end
|
|
57
|
+
else
|
|
58
|
+
mess = "Can't find instruction sequence"
|
|
59
|
+
mess += " for #{args.join(' ')}" unless args.empty?
|
|
60
|
+
errmsg mess
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
if __FILE__ == $0
|
|
67
|
+
# Demo it.
|
|
68
|
+
ISEQS__ = {}
|
|
69
|
+
SCRIPT_ISEQS__ = {}
|
|
70
|
+
|
|
71
|
+
require_relative '../../mock'
|
|
72
|
+
require_relative '../../subcmd'
|
|
73
|
+
name = File.basename(__FILE__, '.rb')
|
|
74
|
+
|
|
75
|
+
# FIXME: DRY the below code
|
|
76
|
+
dbgr, cmd = MockDebugger::setup('info')
|
|
77
|
+
subcommand = Trepan::Subcommand::InfoIseq.new(cmd)
|
|
78
|
+
testcmdMgr = Trepan::Subcmd.new(subcommand)
|
|
79
|
+
|
|
80
|
+
subcommand.run_show_bool
|
|
81
|
+
name = File.basename(__FILE__, '.rb')
|
|
82
|
+
subcommand.summary_help(name)
|
|
83
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require 'columnize'
|
|
4
|
+
require_relative '../base/subcmd'
|
|
5
|
+
require_relative '../../../app/frame'
|
|
6
|
+
|
|
7
|
+
class Trepan::Subcommand::InfoLocals < Trepan::Subcommand
|
|
8
|
+
unless defined?(HELP)
|
|
9
|
+
HELP = 'Show local variables of the current stack frame'
|
|
10
|
+
MAX_ARGS = 1
|
|
11
|
+
MIN_ABBREV = 'lo'.size
|
|
12
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
13
|
+
NEED_STACK = true
|
|
14
|
+
PREFIX = %w(info locals)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
include Trepan::Frame
|
|
18
|
+
def get_local_names
|
|
19
|
+
iseq = @proc.frame.iseq
|
|
20
|
+
0.upto(iseq.local_size-2).map do
|
|
21
|
+
|i|
|
|
22
|
+
iseq.local_name(i)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def run(args)
|
|
27
|
+
if args.size == 3
|
|
28
|
+
if 0 == 'names'.index(args[-1].downcase)
|
|
29
|
+
if 'CFUNC' == @proc.frame.type
|
|
30
|
+
errmsg('info local names not supported for C frames')
|
|
31
|
+
else
|
|
32
|
+
local_names = get_local_names()
|
|
33
|
+
if local_names.empty?
|
|
34
|
+
msg "No local variables defined."
|
|
35
|
+
else
|
|
36
|
+
msg "Local variable names:"
|
|
37
|
+
width = settings[:maxwidth]
|
|
38
|
+
mess = Columnize::columnize(local_names,
|
|
39
|
+
@proc.settings[:maxwidth], ', ',
|
|
40
|
+
false, true, ' ' * 2).chomp
|
|
41
|
+
msg mess
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
else
|
|
45
|
+
errmsg("unrecognized argument #{args[2]}")
|
|
46
|
+
end
|
|
47
|
+
elsif args.size == 2
|
|
48
|
+
if 'CFUNC' == @proc.frame.type
|
|
49
|
+
argc = @proc.frame.argc
|
|
50
|
+
if argc > 0
|
|
51
|
+
1.upto(argc).each do |i|
|
|
52
|
+
msg "#{i}: #{@proc.frame.sp(argc-i+3).inspect}"
|
|
53
|
+
end
|
|
54
|
+
else
|
|
55
|
+
msg("No parameters in C call; showing other C locals is not supported.")
|
|
56
|
+
end
|
|
57
|
+
else
|
|
58
|
+
local_names = get_local_names
|
|
59
|
+
if local_names.empty?
|
|
60
|
+
msg "No local variables defined."
|
|
61
|
+
else
|
|
62
|
+
msg "Local variables:"
|
|
63
|
+
get_local_names.each_with_index do |var_name, i|
|
|
64
|
+
var_value = @proc.safe_rep(@proc.debug_eval_no_errmsg(var_name).inspect)
|
|
65
|
+
msg("#{var_name} = #{var_value}")
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
else
|
|
70
|
+
errmsg("Wrong number of arguments #{args.size}")
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
if __FILE__ == $0
|
|
76
|
+
# Demo it.
|
|
77
|
+
require_relative '../../mock'
|
|
78
|
+
require_relative '../../subcmd'
|
|
79
|
+
name = File.basename(__FILE__, '.rb')
|
|
80
|
+
|
|
81
|
+
# FIXME: DRY the below code
|
|
82
|
+
dbgr, cmd = MockDebugger::setup('info')
|
|
83
|
+
subcommand = Trepan::Subcommand::InfoLocals.new(cmd)
|
|
84
|
+
testcmdMgr = Trepan::Subcmd.new(subcommand)
|
|
85
|
+
|
|
86
|
+
name = File.basename(__FILE__, '.rb')
|
|
87
|
+
subcommand.summary_help(name)
|
|
88
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative '../base/subcmd'
|
|
4
|
+
|
|
5
|
+
class Trepan::Subcommand::InfoProgram < Trepan::Subcommand
|
|
6
|
+
unless defined?(HELP)
|
|
7
|
+
HELP = 'Information about debugged program and its environment'
|
|
8
|
+
MIN_ABBREV = 'pr'.size
|
|
9
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
10
|
+
NEED_STACK = true
|
|
11
|
+
PREFIX = %w(info program)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def run(args)
|
|
15
|
+
frame = @proc.frame
|
|
16
|
+
m = 'Program stop event: %s' % @proc.event
|
|
17
|
+
m +=
|
|
18
|
+
if frame.iseq
|
|
19
|
+
'; PC offset %d of instruction sequence: %s' %
|
|
20
|
+
[frame.pc_offset, frame.iseq.name]
|
|
21
|
+
else
|
|
22
|
+
'.'
|
|
23
|
+
end
|
|
24
|
+
msg m
|
|
25
|
+
if 'return' == @proc.event
|
|
26
|
+
msg 'R=> %s' % @proc.frame.sp(1).inspect
|
|
27
|
+
elsif 'raise' == @proc.event
|
|
28
|
+
msg @proc.core.hook_arg.inspect if @proc.core.hook_arg
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
if @proc.brkpt
|
|
32
|
+
msg('It is stopped at %sbreakpoint %d.' %
|
|
33
|
+
[@proc.brkpt.temp? ? 'temporary ' : '',
|
|
34
|
+
@proc.brkpt.id])
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
if __FILE__ == $0
|
|
41
|
+
# Demo it.
|
|
42
|
+
require_relative '../../mock'
|
|
43
|
+
name = File.basename(__FILE__, '.rb')
|
|
44
|
+
|
|
45
|
+
# FIXME: DRY the below code
|
|
46
|
+
dbgr, cmd = MockDebugger::setup('info')
|
|
47
|
+
subcommand = Trepan::Subcommand::InfoProgram.new(cmd)
|
|
48
|
+
testcmdMgr = Trepan::Subcmd.new(subcommand)
|
|
49
|
+
|
|
50
|
+
name = File.basename(__FILE__, '.rb')
|
|
51
|
+
subcommand.run([name])
|
|
52
|
+
subcommand.summary_help(name)
|
|
53
|
+
puts
|
|
54
|
+
end
|