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,38 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative '../../base/subsubcmd'
|
|
4
|
+
|
|
5
|
+
class Trepan::SubSubcommand::ShowTracePrint < Trepan::ShowBoolSubSubcommand
|
|
6
|
+
unless defined?(HELP)
|
|
7
|
+
HELP = "Show tracing print status"
|
|
8
|
+
MIN_ABBREV = 'p'.size
|
|
9
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
10
|
+
PREFIX = %w(show trace buffer)
|
|
11
|
+
SHORT_HELP = "Show tracing print status"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
if __FILE__ == $0
|
|
17
|
+
# Demo it.
|
|
18
|
+
require_relative '../../../mock'
|
|
19
|
+
require_relative '../../../subcmd'
|
|
20
|
+
name = File.basename(__FILE__, '.rb')
|
|
21
|
+
|
|
22
|
+
# FIXME: DRY the below code
|
|
23
|
+
dbgr, show_cmd = MockDebugger::setup('show')
|
|
24
|
+
testcmdMgr = Trepan::Subcmd.new(show_cmd)
|
|
25
|
+
trace_cmd = Trepan::SubSubcommand::ShowTrace.new(dbgr.core.processor,
|
|
26
|
+
show_cmd)
|
|
27
|
+
|
|
28
|
+
# FIXME: remove the 'join' below
|
|
29
|
+
cmd_name = Trepan::SubSubcommand::ShowTracePrint::PREFIX.join('')
|
|
30
|
+
tb_cmd = Trepan::SubSubcommand::ShowTracePrint.new(show_cmd.proc,
|
|
31
|
+
trace_cmd,
|
|
32
|
+
cmd_name)
|
|
33
|
+
# require_relative '../../../../lib/trepanning'
|
|
34
|
+
# dbgr = Trepan.new(:set_restart => true)
|
|
35
|
+
# dbgr.debugger
|
|
36
|
+
tb_cmd.run([])
|
|
37
|
+
|
|
38
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
|
|
4
|
+
# Our local modules
|
|
5
|
+
require_relative 'base/cmd'
|
|
6
|
+
require_relative '../../interface/script'
|
|
7
|
+
# Mfile = import_relative('file', '...lib', 'pydbgr')
|
|
8
|
+
|
|
9
|
+
class Trepan::Command::SourceCommand < Trepan::Command
|
|
10
|
+
unless defined?(HELP)
|
|
11
|
+
HELP = "source [-v][-Y|-N][-c] FILE
|
|
12
|
+
|
|
13
|
+
Read debugger commands from a file named FILE. Optional -v switch
|
|
14
|
+
(before the filename) causes each command in FILE to be echoed as it
|
|
15
|
+
is executed. Option -Y sets the default value in any confirmation
|
|
16
|
+
command to be 'yes' and -N sets the default value to 'no'.
|
|
17
|
+
|
|
18
|
+
Note that the command startup file '.pydbgrc' is read automatically
|
|
19
|
+
via a source command the debugger is started.
|
|
20
|
+
|
|
21
|
+
An error in any command terminates execution of the command file
|
|
22
|
+
unless option -c is given.
|
|
23
|
+
"
|
|
24
|
+
CATEGORY = 'support'
|
|
25
|
+
MIN_ARGS = 1 # Need at least this many
|
|
26
|
+
MAX_ARGS = nil
|
|
27
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
28
|
+
SHORT_HELP = 'Read and run debugger commands from a file'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def run(args)
|
|
32
|
+
verbose = false
|
|
33
|
+
parms = args[1..-1]
|
|
34
|
+
opts = {}
|
|
35
|
+
parms.each do |arg|
|
|
36
|
+
case arg
|
|
37
|
+
when '-v'
|
|
38
|
+
opts[:verbose] = true
|
|
39
|
+
when '-Y'
|
|
40
|
+
opts[:confirm_val] = true
|
|
41
|
+
when '-N'
|
|
42
|
+
opts[:confirm_val] = false
|
|
43
|
+
when '-c'
|
|
44
|
+
opts[:abort_on_error] = false
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
filename = args[-1]
|
|
49
|
+
|
|
50
|
+
expanded_file = File.expand_path(filename)
|
|
51
|
+
unless File.readable?(expanded_file)
|
|
52
|
+
errmsg("Debugger command file '%s' is not a readable file" % filename)
|
|
53
|
+
return false
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Push a new debugger interface.
|
|
57
|
+
intf = @proc.dbgr.intf
|
|
58
|
+
script_intf = Trepan::ScriptInterface.new(expanded_file,
|
|
59
|
+
intf[-1].output,
|
|
60
|
+
opts)
|
|
61
|
+
intf << script_intf
|
|
62
|
+
return false
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Demo it
|
|
67
|
+
if __FILE__ == $0
|
|
68
|
+
require_relative '../mock'
|
|
69
|
+
name = File.basename(__FILE__, '.rb')
|
|
70
|
+
dbgr, cmd = MockDebugger::setup(name)
|
|
71
|
+
if ARGV.size > 1
|
|
72
|
+
cmd.run([name, *ARGV])
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative 'base/cmd'
|
|
4
|
+
require_relative '../../app/condition'
|
|
5
|
+
class Trepan::Command::StepCommand < Trepan::Command
|
|
6
|
+
|
|
7
|
+
unless defined?(HELP)
|
|
8
|
+
HELP =
|
|
9
|
+
"step[+|=|-|<|>|!|<>] [into] [EVENT-NAME...] [count]
|
|
10
|
+
step until EXPRESSION
|
|
11
|
+
step thread
|
|
12
|
+
step to METHOD-NAME
|
|
13
|
+
step over
|
|
14
|
+
step out
|
|
15
|
+
|
|
16
|
+
Execute the current line, stopping at the next event. Sometimes this
|
|
17
|
+
is called 'step into'.
|
|
18
|
+
|
|
19
|
+
With an integer argument, step that many times. With an 'until'
|
|
20
|
+
expression that expression is evaluated and we stop the first time it
|
|
21
|
+
is true.
|
|
22
|
+
|
|
23
|
+
EVENT-NAME... is list of an event name which is one on 'call',
|
|
24
|
+
'return', 'line', 'exception' 'c-call', 'c-return' or 'c-exception'.
|
|
25
|
+
If specified, only those stepping events will be considered. If no
|
|
26
|
+
list of event names is given, then any event triggers a stop when the
|
|
27
|
+
count is 0.
|
|
28
|
+
|
|
29
|
+
There is however another way to specify an *single* EVENT-NAME, by
|
|
30
|
+
suffixing one of the symbols '<', '>', or '!' after the command or on
|
|
31
|
+
an alias of that. A suffix of '+' on a command or an alias forces a
|
|
32
|
+
move to another position, while a suffix of '-' disables this
|
|
33
|
+
requirement. A suffix of '>' will continue until the next
|
|
34
|
+
call. ('finish' will run run until the return for that call.)
|
|
35
|
+
|
|
36
|
+
If no suffix is given, the debugger setting 'different' determines
|
|
37
|
+
this behavior.
|
|
38
|
+
|
|
39
|
+
Examples:
|
|
40
|
+
step # step 1 event, *any* event obeying 'set different' setting
|
|
41
|
+
step 1 # same as above
|
|
42
|
+
step+ # same but force stopping on a new line
|
|
43
|
+
step= # same but force stopping on a new line a new frame added
|
|
44
|
+
step- # same but force stopping on a new line a new frame added
|
|
45
|
+
step 5/5+0 # same as above
|
|
46
|
+
step line # step only line events
|
|
47
|
+
step call # step only call call events
|
|
48
|
+
step> # step call and C-call events
|
|
49
|
+
step< # step only return and C-return events
|
|
50
|
+
step call line # Step line *and* call events
|
|
51
|
+
step<> # same as step call c-call return c-return
|
|
52
|
+
step until a > b
|
|
53
|
+
step over # same as 'next'
|
|
54
|
+
step out # same as 'finish'
|
|
55
|
+
step thread # step stopping only in the current thread. Is the same
|
|
56
|
+
# as step until Thread.current.object_id == #object_id
|
|
57
|
+
|
|
58
|
+
Related and similar is the 'next' (step over) and 'finish' (step out)
|
|
59
|
+
commands. All of these are slower than running to a breakpoint.
|
|
60
|
+
|
|
61
|
+
See also the commands:
|
|
62
|
+
'skip', 'jump' (there's no 'hop' yet), 'continue', 'return' and
|
|
63
|
+
'finish' for other ways to progress execution.
|
|
64
|
+
"
|
|
65
|
+
|
|
66
|
+
ALIASES = %w(s step+ step- step< step> step<> step! s> s< s+ s-
|
|
67
|
+
s<> s! s=)
|
|
68
|
+
CATEGORY = 'running'
|
|
69
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
70
|
+
NEED_RUNNING = true
|
|
71
|
+
SHORT_HELP = 'Step program (possibly entering called functions)'
|
|
72
|
+
|
|
73
|
+
Keyword_to_related_cmd = {
|
|
74
|
+
'out' => 'finish',
|
|
75
|
+
'over' => 'next',
|
|
76
|
+
'into' => 'step',
|
|
77
|
+
}
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
include Trepan::Condition
|
|
81
|
+
# This method runs the command
|
|
82
|
+
def run(args) # :nodoc
|
|
83
|
+
opts = @proc.parse_next_step_suffix(args[0])
|
|
84
|
+
condition = nil
|
|
85
|
+
if args.size == 1
|
|
86
|
+
# Form is: "step" which means "step 1"
|
|
87
|
+
step_count = 0
|
|
88
|
+
else
|
|
89
|
+
replace_cmd = Keyword_to_related_cmd[args[1]]
|
|
90
|
+
if replace_cmd
|
|
91
|
+
cmd = @proc.commands[replace_cmd]
|
|
92
|
+
return cmd.run([replace_cmd] + args[2..-1])
|
|
93
|
+
elsif 'until' == args[1]
|
|
94
|
+
try_condition = args[2..-1].join(' ')
|
|
95
|
+
if valid_condition?(try_condition)
|
|
96
|
+
condition = try_condition
|
|
97
|
+
opts[:different_pos] = false
|
|
98
|
+
step_count = 0
|
|
99
|
+
end
|
|
100
|
+
elsif 'to' == args[1]
|
|
101
|
+
if args.size != 3
|
|
102
|
+
errmsg('Expecting a method name after "to"')
|
|
103
|
+
return
|
|
104
|
+
elsif !@proc.method?(args[2])
|
|
105
|
+
errmsg("#{args[2]} doesn't seem to be a method name")
|
|
106
|
+
return
|
|
107
|
+
else
|
|
108
|
+
opts[:to_method] = args[2]
|
|
109
|
+
opts[:different_pos] = false
|
|
110
|
+
step_count = 0
|
|
111
|
+
end
|
|
112
|
+
elsif 'thread' == args[1]
|
|
113
|
+
condition = "Thread.current.object_id == #{Thread.current.object_id}"
|
|
114
|
+
opts[:different_pos] = false
|
|
115
|
+
step_count = 0
|
|
116
|
+
else
|
|
117
|
+
count_str = args[1]
|
|
118
|
+
int_opts = {
|
|
119
|
+
:msg_on_error =>
|
|
120
|
+
"The 'step' command argument must eval to an integer. Got: %s" %
|
|
121
|
+
count_str,
|
|
122
|
+
:min_value => 1
|
|
123
|
+
}.merge(opts)
|
|
124
|
+
count = @proc.get_an_int(count_str, int_opts)
|
|
125
|
+
return unless count
|
|
126
|
+
# step 1 is core.step_count = 0 or "stop next event"
|
|
127
|
+
step_count = count - 1
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
@proc.step(step_count, opts, condition)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
if __FILE__ == $0
|
|
135
|
+
require_relative '../mock'
|
|
136
|
+
name = File.basename(__FILE__, '.rb')
|
|
137
|
+
dbgr, cmd = MockDebugger::setup(name)
|
|
138
|
+
p cmd.run([name])
|
|
139
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative 'base/cmd'
|
|
4
|
+
require_relative '../../app/condition'
|
|
5
|
+
class Trepan::Command::StepICommand < Trepan::Command
|
|
6
|
+
|
|
7
|
+
unless defined?(HELP)
|
|
8
|
+
HELP =
|
|
9
|
+
"stepi
|
|
10
|
+
|
|
11
|
+
Step by VM instruction(s).
|
|
12
|
+
|
|
13
|
+
Examples:
|
|
14
|
+
stepi # step 1 instruction
|
|
15
|
+
stepi 1 # same as above
|
|
16
|
+
|
|
17
|
+
Related and similar is the 'step', 'next' (step over) and 'finish' (step out)
|
|
18
|
+
commands. All of these are slower than running to a breakpoint.
|
|
19
|
+
|
|
20
|
+
See also the commands:
|
|
21
|
+
'skip', 'jump' (there's no 'hop' yet), 'continue', 'return' and
|
|
22
|
+
'finish' for other ways to progress execution.
|
|
23
|
+
"
|
|
24
|
+
|
|
25
|
+
CATEGORY = 'running'
|
|
26
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
27
|
+
NEED_RUNNING = true
|
|
28
|
+
SHORT_HELP = 'Step VM instruction(s)'
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
include Trepan::Condition
|
|
33
|
+
# This method runs the command
|
|
34
|
+
def run(args) # :nodoc
|
|
35
|
+
opts = {:stop_events => Set.new(%w(insn))}
|
|
36
|
+
@proc.core.step_events |= Trace::INSN_EVENT_MASK
|
|
37
|
+
condition = nil
|
|
38
|
+
if args.size == 1
|
|
39
|
+
# Form is: "step" which means "step 1"
|
|
40
|
+
step_count = 0
|
|
41
|
+
else
|
|
42
|
+
count_str = args[1]
|
|
43
|
+
int_opts = {
|
|
44
|
+
:msg_on_error =>
|
|
45
|
+
"The 'step' command argument must eval to an integer. Got: %s" %
|
|
46
|
+
count_str,
|
|
47
|
+
:min_value => 1
|
|
48
|
+
}.merge(opts)
|
|
49
|
+
count = @proc.get_an_int(count_str, int_opts)
|
|
50
|
+
return unless count
|
|
51
|
+
# step 1 is core.step_count = 0 or "stop next event"
|
|
52
|
+
step_count = count - 1
|
|
53
|
+
end
|
|
54
|
+
@proc.step(step_count, opts, condition)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
if __FILE__ == $0
|
|
59
|
+
require_relative '../mock'
|
|
60
|
+
name = File.basename(__FILE__, '.rb')
|
|
61
|
+
dbgr, cmd = MockDebugger::setup(name)
|
|
62
|
+
p cmd.run([name])
|
|
63
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
2
|
+
require_relative 'base/cmd'
|
|
3
|
+
|
|
4
|
+
class Trepan::Command::UnaliasCommand < Trepan::Command
|
|
5
|
+
|
|
6
|
+
unless defined?(HELP)
|
|
7
|
+
HELP =
|
|
8
|
+
"unalias COMMAND
|
|
9
|
+
|
|
10
|
+
Remove alias for COMMAND
|
|
11
|
+
|
|
12
|
+
See also 'alias'.
|
|
13
|
+
"
|
|
14
|
+
|
|
15
|
+
CATEGORY = 'support'
|
|
16
|
+
MIN_ARGS = 1
|
|
17
|
+
# MAX_ARGS = 1 # Need at most this many
|
|
18
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
19
|
+
NEED_STACK = true
|
|
20
|
+
SHORT_HELP = 'Remove an alias'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Run command.
|
|
24
|
+
def run(args)
|
|
25
|
+
args[1..-1].each do |arg|
|
|
26
|
+
if @proc.aliases.member?(arg)
|
|
27
|
+
@proc.aliases.delete(arg)
|
|
28
|
+
msg "Alias for #{arg} removed."
|
|
29
|
+
else
|
|
30
|
+
msg "No alias found for #{arg}."
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if __FILE__ == $0
|
|
37
|
+
# Demo it.
|
|
38
|
+
require_relative '../mock'
|
|
39
|
+
name = File.basename(__FILE__, '.rb')
|
|
40
|
+
dbgr, cmd = MockDebugger::setup(name)
|
|
41
|
+
cmd.run %w(unalias s)
|
|
42
|
+
cmd.run %w(unalias s)
|
|
43
|
+
cmd.run %w(unalias foo bar n)
|
|
44
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative 'base/cmd'
|
|
4
|
+
|
|
5
|
+
# undisplay display-number...
|
|
6
|
+
class Trepan::Command::UndisplayCommand < Trepan::Command
|
|
7
|
+
|
|
8
|
+
unless defined?(HELP)
|
|
9
|
+
HELP = <<EOH
|
|
10
|
+
|
|
11
|
+
undisplay DISPLAY_NUMBER ...
|
|
12
|
+
Cancel some expressions to be displayed when program stops.
|
|
13
|
+
Arguments are the code numbers of the expressions to stop displaying.
|
|
14
|
+
No argument means cancel all automatic-display expressions.
|
|
15
|
+
"delete display" has the same effect as this command.
|
|
16
|
+
Do "info display" to see current list of code numbers.
|
|
17
|
+
EOH
|
|
18
|
+
|
|
19
|
+
ALIASES = %w(und)
|
|
20
|
+
CATEGORY = 'data'
|
|
21
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
22
|
+
NEED_STACK = false
|
|
23
|
+
SHORT_HELP = 'Cancel some expressions to be displayed when program stops'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def run(args)
|
|
27
|
+
|
|
28
|
+
if args.size == 1
|
|
29
|
+
@proc.displays.clear
|
|
30
|
+
return
|
|
31
|
+
end
|
|
32
|
+
opts = {}
|
|
33
|
+
args[1..-1].each do |arg|
|
|
34
|
+
opts[:msg_on_error] = '%s must be a display number' % arg
|
|
35
|
+
i = @proc.get_an_int(arg, opts)
|
|
36
|
+
if i
|
|
37
|
+
unless @proc.displays.delete_index(i)
|
|
38
|
+
errmsg("no display number %d." % i)
|
|
39
|
+
return
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
return false
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
if __FILE__ == $0
|
|
48
|
+
# demo it.
|
|
49
|
+
require 'thread_frame'
|
|
50
|
+
require_relative '../mock'
|
|
51
|
+
name = File.basename(__FILE__, '.rb')
|
|
52
|
+
dbgr, cmd = MockDebugger::setup(name)
|
|
53
|
+
|
|
54
|
+
def run_cmd(cmd, args)
|
|
55
|
+
cmd.run(args)
|
|
56
|
+
puts '==' * 10
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
cmd.proc.frame_setup(RubyVM::ThreadFrame::current)
|
|
60
|
+
|
|
61
|
+
run_cmd(cmd, %w(undisplay z))
|
|
62
|
+
run_cmd(cmd, %w(undisplay 1 10))
|
|
63
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
2
|
+
require_relative 'base/cmd'
|
|
3
|
+
|
|
4
|
+
# up command. Like 'down' butthe direction (set by DIRECTION) is different.
|
|
5
|
+
#
|
|
6
|
+
# NOTE: The down command subclasses this, so beware when changing!
|
|
7
|
+
class Trepan::Command::UpCommand < Trepan::Command
|
|
8
|
+
|
|
9
|
+
# Silence already initialized constant .. warnings
|
|
10
|
+
old_verbose = $VERBOSE
|
|
11
|
+
$VERBOSE = nil
|
|
12
|
+
HELP =
|
|
13
|
+
"u(p) [count]
|
|
14
|
+
|
|
15
|
+
Move the current frame up in the stack trace (to an older frame). 0 is
|
|
16
|
+
the most recent frame. If no count is given, move up 1.
|
|
17
|
+
|
|
18
|
+
See also 'down' and 'frame'.
|
|
19
|
+
"
|
|
20
|
+
|
|
21
|
+
ALIASES = %w(u)
|
|
22
|
+
CATEGORY = 'stack'
|
|
23
|
+
MAX_ARGS = 1 # Need at most this many
|
|
24
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
25
|
+
NEED_STACK = true
|
|
26
|
+
SHORT_HELP = 'Move frame in the direction of the caller of the last-selected frame'
|
|
27
|
+
$VERBOSE = old_verbose
|
|
28
|
+
|
|
29
|
+
require_relative '../../app/frame'
|
|
30
|
+
include Trepan::Frame
|
|
31
|
+
|
|
32
|
+
def initialize(proc)
|
|
33
|
+
super
|
|
34
|
+
@direction = +1 # -1 for down.
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Run 'up' command.
|
|
38
|
+
def run(args)
|
|
39
|
+
|
|
40
|
+
# FIXME: move into @proc and test based on NEED_STACK.
|
|
41
|
+
if not @proc.top_frame
|
|
42
|
+
errmsg('No frames recorded.')
|
|
43
|
+
return false
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
if args.size == 1
|
|
47
|
+
# Form is: "down" which means "down 1"
|
|
48
|
+
count = 1
|
|
49
|
+
else
|
|
50
|
+
stack_size = @proc.top_frame.stack_size - @proc.hide_level
|
|
51
|
+
count_str = args[1]
|
|
52
|
+
name_or_id = args[1]
|
|
53
|
+
opts = {
|
|
54
|
+
:msg_on_error =>
|
|
55
|
+
"The '#{NAME}' command argument requires a frame number. Got: %s" % count_str,
|
|
56
|
+
:min_value => -stack_size,
|
|
57
|
+
:max_value => stack_size-1
|
|
58
|
+
}
|
|
59
|
+
count = @proc.get_an_int(count_str, opts)
|
|
60
|
+
return false unless count
|
|
61
|
+
end
|
|
62
|
+
@proc.adjust_frame(@direction * count, false)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
if __FILE__ == $0
|
|
67
|
+
# Demo it.
|
|
68
|
+
require 'thread_frame'
|
|
69
|
+
require_relative '../mock'
|
|
70
|
+
name = File.basename(__FILE__, '.rb')
|
|
71
|
+
dbgr, cmd = MockDebugger::setup(name)
|
|
72
|
+
|
|
73
|
+
def sep ; puts '=' * 40 end
|
|
74
|
+
cmd.run [name]
|
|
75
|
+
%w(-1 0 1 -2).each do |count|
|
|
76
|
+
puts "#{name} #{count}"
|
|
77
|
+
cmd.run([name, count])
|
|
78
|
+
sep
|
|
79
|
+
end
|
|
80
|
+
def foo(cmd, name)
|
|
81
|
+
cmd.proc.frame_setup(RubyVM::ThreadFrame::current)
|
|
82
|
+
puts "#{name}"
|
|
83
|
+
cmd.run([name])
|
|
84
|
+
sep
|
|
85
|
+
%w(-2 -1).each do |count|
|
|
86
|
+
puts "#{name} #{count}"
|
|
87
|
+
cmd.run([name, count])
|
|
88
|
+
sep
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
foo(cmd, name)
|
|
92
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
2
|
+
require_relative '../app/default'
|
|
3
|
+
class Trepan
|
|
4
|
+
class CmdProcessor
|
|
5
|
+
|
|
6
|
+
DEFAULT_SETTINGS = {
|
|
7
|
+
:autoeval => true, # Ruby eval non-debugger commands
|
|
8
|
+
:autoirb => false, # Go into IRB in debugger command loop
|
|
9
|
+
:autolist => false, # Run 'list'
|
|
10
|
+
|
|
11
|
+
:basename => false, # Show basename of filenames only
|
|
12
|
+
:different => 'nostack', # stop *only* when different position?
|
|
13
|
+
|
|
14
|
+
:debugdbgr => false, # Debugging the debugger
|
|
15
|
+
:debugexcept => true, # Internal debugging of command exceptions
|
|
16
|
+
:debugmacro => false, # debugging macros
|
|
17
|
+
:debugskip => false, # Internal debugging of step/next skipping
|
|
18
|
+
:debugstack => false, # How hidden outer debugger stack frames
|
|
19
|
+
:directory => # last-resort path-search for files
|
|
20
|
+
'$cdir:$cwd', # that are not fully qualified.
|
|
21
|
+
|
|
22
|
+
:maxlist => 10, # Number of source lines to list
|
|
23
|
+
:maxstack => 10, # backtrace limit
|
|
24
|
+
:maxstring => 150, # Strings which are larger than this
|
|
25
|
+
# will be truncated to this length when
|
|
26
|
+
# printed
|
|
27
|
+
:maxwidth => (ENV['COLUMNS'] || '80').to_i,
|
|
28
|
+
:prompt => 'trepan', # core part of prompt. Additional info like
|
|
29
|
+
# debug nesting and
|
|
30
|
+
:save_cmdfile => nil, # If set, debugger command file to be
|
|
31
|
+
# used on restart
|
|
32
|
+
:timer => false, # show elapsed time between events
|
|
33
|
+
:traceprint => false, # event tracing printing
|
|
34
|
+
:tracebuffer => false, # save events to a trace buffer.
|
|
35
|
+
:user_cmd_dir => File.join(Trepanning::HOME_DIR, 'trepan', 'command'),
|
|
36
|
+
# User command directory
|
|
37
|
+
} unless defined?(DEFAULT_SETTINGS)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
if __FILE__ == $0
|
|
42
|
+
# Show it:
|
|
43
|
+
require 'pp'
|
|
44
|
+
PP.pp(Trepan::CmdProcessor::DEFAULT_SETTINGS)
|
|
45
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
2
|
+
require_relative '../app/display'
|
|
3
|
+
class Trepan
|
|
4
|
+
class CmdProcessor
|
|
5
|
+
attr_reader :displays
|
|
6
|
+
|
|
7
|
+
def display_initialize
|
|
8
|
+
@displays = DisplayMgr.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def run_eval_display(args={})
|
|
12
|
+
for line in @displays.display(@frame) do
|
|
13
|
+
msg(line)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
data/processor/eval.rb
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
2
|
+
class Trepan
|
|
3
|
+
class CmdProcessor
|
|
4
|
+
|
|
5
|
+
def debug_eval(str, max_fake_filename=15)
|
|
6
|
+
begin
|
|
7
|
+
debug_eval_with_exception(str, max_fake_filename)
|
|
8
|
+
rescue SyntaxError, StandardError, ScriptError => e
|
|
9
|
+
exception_dump(e, @settings[:stack_trace_on_error], $!.backtrace)
|
|
10
|
+
nil
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def debug_eval_with_exception(str, max_fake_filename=15)
|
|
15
|
+
filename, b = get_binding_and_filename(str, max_fake_filename)
|
|
16
|
+
eval(str, b, filename)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def debug_eval_no_errmsg(str, max_fake_filename=15)
|
|
20
|
+
begin
|
|
21
|
+
debug_eval_with_exception(str, max_fake_filename)
|
|
22
|
+
rescue SyntaxError, StandardError, ScriptError => e
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def exception_dump(e, stack_trace, backtrace)
|
|
28
|
+
str = "#{e.class} Exception:\n\t#{e.message}"
|
|
29
|
+
if stack_trace
|
|
30
|
+
str += "\n" + backtrace.map{|l| "\t#{l}"}.join("\n") rescue nil
|
|
31
|
+
end
|
|
32
|
+
msg str
|
|
33
|
+
# throw :debug_error
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def fake_eval_filename(str, maxlen = 15)
|
|
37
|
+
fake_filename =
|
|
38
|
+
if maxlen < str.size
|
|
39
|
+
# FIXME: Guard against \" in positions 13..15?
|
|
40
|
+
str.inspect[0..maxlen-1] + '"...'
|
|
41
|
+
else
|
|
42
|
+
str.inspect
|
|
43
|
+
end
|
|
44
|
+
"(eval #{fake_filename})"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def get_binding_and_filename(str, maxlen)
|
|
48
|
+
b =
|
|
49
|
+
begin
|
|
50
|
+
@frame.binding
|
|
51
|
+
rescue
|
|
52
|
+
binding
|
|
53
|
+
end
|
|
54
|
+
filename = fake_eval_filename(str, maxlen)
|
|
55
|
+
return [filename, b]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
if __FILE__ == $0
|
|
62
|
+
# Demo it.
|
|
63
|
+
cmdp = Trepan::CmdProcessor.new
|
|
64
|
+
puts cmdp.fake_eval_filename('x = 1; y = 2')
|
|
65
|
+
puts cmdp.fake_eval_filename('x = 1; y = 2', 7)
|
|
66
|
+
|
|
67
|
+
def cmdp.errmsg(msg)
|
|
68
|
+
puts "** #{msg}"
|
|
69
|
+
end
|
|
70
|
+
begin
|
|
71
|
+
1/0
|
|
72
|
+
rescue Exception => exc
|
|
73
|
+
cmdp.exception_dump(exc, true, $!.backtrace)
|
|
74
|
+
puts '=' * 40
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
x = 1
|
|
78
|
+
require 'thread_frame'
|
|
79
|
+
cmdp.instance_variable_set('@frame', RubyVM::ThreadFrame.current)
|
|
80
|
+
cmdp.instance_variable_set('@settings', {:stack_trace_on_error => true})
|
|
81
|
+
def cmdp.errmsg(mess) ; puts mess end
|
|
82
|
+
puts cmdp.debug_eval('x = "#{x}"')
|
|
83
|
+
puts cmdp.debug_eval('x+')
|
|
84
|
+
puts cmdp.debug_eval_no_errmsg('y+')
|
|
85
|
+
puts '=' * 40
|
|
86
|
+
puts cmdp.debug_eval('y = 1; x+', 4)
|
|
87
|
+
puts '=' * 40
|
|
88
|
+
end
|