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,72 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative '../base/subsubcmd'
|
|
4
|
+
require_relative '../base/subsubmgr'
|
|
5
|
+
|
|
6
|
+
class Trepan::SubSubcommand::InfoRegisters < Trepan::SubSubcommandMgr
|
|
7
|
+
unless defined?(HELP)
|
|
8
|
+
HELP =
|
|
9
|
+
'List of contents for the registers of the current stack frame.
|
|
10
|
+
If a register name given, only only that register is show.
|
|
11
|
+
|
|
12
|
+
Examples:
|
|
13
|
+
info registers # show all registers
|
|
14
|
+
info register pc # show only the pc register
|
|
15
|
+
info reg sp # show all stack pointer registers
|
|
16
|
+
info reg sp 1 3 # show sp(1) and sp(3)
|
|
17
|
+
info reg sp size # show sp size
|
|
18
|
+
info reg lfp # show lfp(0)
|
|
19
|
+
'
|
|
20
|
+
|
|
21
|
+
MIN_ABBREV = 'reg'.size # Note we have "info return"
|
|
22
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
23
|
+
NEED_STACK = true
|
|
24
|
+
PREFIX = %w(info registers)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def run(args)
|
|
28
|
+
|
|
29
|
+
args = @parent.last_args
|
|
30
|
+
unavailable_regs =
|
|
31
|
+
if 'CFUNC' == @proc.frame.type
|
|
32
|
+
%w(inforegisterslfp inforegisterspc)
|
|
33
|
+
else
|
|
34
|
+
[]
|
|
35
|
+
end
|
|
36
|
+
all_regs = @subcmds.subcmds.keys.sort - unavailable_regs
|
|
37
|
+
|
|
38
|
+
if args.size == 2
|
|
39
|
+
# Form is: "info registers"
|
|
40
|
+
all_regs.sort.each do |subcmd_name|
|
|
41
|
+
@subcmds.subcmds[subcmd_name].run([])
|
|
42
|
+
end
|
|
43
|
+
else
|
|
44
|
+
subcmd_name = args[2]
|
|
45
|
+
key_name = PREFIX.join('') + subcmd_name
|
|
46
|
+
remain_args = args[3..-1]
|
|
47
|
+
if all_regs.member?(key_name)
|
|
48
|
+
@subcmds.subcmds[key_name].run(remain_args)
|
|
49
|
+
elsif unavailable_regs.member?(key_name)
|
|
50
|
+
msg("info registers: %s can not be displayed for frame type %s." %
|
|
51
|
+
[subcmd_name, @proc.frame.type])
|
|
52
|
+
else
|
|
53
|
+
errmsg("info registers: %s is not a valid register name" % subcmd_name)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
if __FILE__ == $0
|
|
60
|
+
# Demo it.
|
|
61
|
+
require_relative '../../mock'
|
|
62
|
+
dbgr = MockDebugger::MockDebugger.new
|
|
63
|
+
cmds = dbgr.core.processor.commands
|
|
64
|
+
info_cmd = cmds['info']
|
|
65
|
+
command = Trepan::SubSubcommand::InfoRegisters.new(dbgr.core.processor,
|
|
66
|
+
info_cmd)
|
|
67
|
+
name = File.basename(__FILE__, '.rb')
|
|
68
|
+
cmd_args = ['info', name]
|
|
69
|
+
info_cmd.instance_variable_set('@last_args', cmd_args)
|
|
70
|
+
command.proc.frame_setup(RubyVM::ThreadFrame::current)
|
|
71
|
+
command.run(cmd_args)
|
|
72
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative '../../base/subsubcmd'
|
|
4
|
+
require_relative 'helper'
|
|
5
|
+
|
|
6
|
+
class Trepan::Subcommand::InfoRegistersDfp < Trepan::SubSubcommand
|
|
7
|
+
unless defined?(HELP)
|
|
8
|
+
HELP = 'Show the value of the VM dynamic frame pointer (DFP)'
|
|
9
|
+
MIN_ABBREV = 'lf'.size
|
|
10
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
11
|
+
NEED_STACK = true
|
|
12
|
+
PREFIX = %w(info registers dfp)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
include Registers
|
|
16
|
+
def run(args)
|
|
17
|
+
register_array_index(PREFIX[-1], args)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
if __FILE__ == $0
|
|
22
|
+
# Demo it.
|
|
23
|
+
require_relative '../../../mock'
|
|
24
|
+
require_relative '../../../subcmd'
|
|
25
|
+
name = File.basename(__FILE__, '.rb')
|
|
26
|
+
|
|
27
|
+
# FIXME: DRY the below code
|
|
28
|
+
dbgr, info_cmd = MockDebugger::setup('info')
|
|
29
|
+
testcmdMgr = Trepan::Subcmd.new(info_cmd)
|
|
30
|
+
cmd_name = Trepan::SubSubcommand::InfoRegistersDfp::PREFIX.join('')
|
|
31
|
+
infox_cmd = Trepan::SubSubcommand::InfoRegistersDfp.new(info_cmd.proc,
|
|
32
|
+
info_cmd,
|
|
33
|
+
cmd_name)
|
|
34
|
+
infox_cmd.run([])
|
|
35
|
+
|
|
36
|
+
# name = File.basename(__FILE__, '.rb')
|
|
37
|
+
# subcommand.summary_help(name)
|
|
38
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
2
|
+
module Registers
|
|
3
|
+
def register_array_index(name, args, max_value=nil)
|
|
4
|
+
if args.size == 0
|
|
5
|
+
# Form is: "info xx" which means "info xx 0"
|
|
6
|
+
lookup_pos = position = 0
|
|
7
|
+
else
|
|
8
|
+
position_str = args[0]
|
|
9
|
+
opts = {
|
|
10
|
+
:msg_on_error =>
|
|
11
|
+
"The 'info registers %s' command argument must eval to an integer. Got: %s" % [name, position_str],
|
|
12
|
+
# :min_value => 0,
|
|
13
|
+
:max_value => max_value
|
|
14
|
+
}
|
|
15
|
+
position = @proc.get_an_int(position_str, opts)
|
|
16
|
+
return nil unless position
|
|
17
|
+
end
|
|
18
|
+
lookup_pos =
|
|
19
|
+
if 'lfp' == name
|
|
20
|
+
max_value + 1 - position
|
|
21
|
+
elsif 'sp' == name && 'CFUNC' == @proc.frame.type
|
|
22
|
+
# && @proc.frame.next.type == 'IFUNC" # ?
|
|
23
|
+
|
|
24
|
+
# FIXME: In C frames there seems to be some vm_push_frame's
|
|
25
|
+
# via perhaps vm_yield_with_cfunc along with sp adjustments.
|
|
26
|
+
# I am not sure if this is under what conditions this
|
|
27
|
+
# *doesn't* happen so until I can figure out the better thing
|
|
28
|
+
# to do, possibly in the Ruby 1.9 interpeter, we'll handle
|
|
29
|
+
# this here. It is also conceivable to handle this in
|
|
30
|
+
# thread_frame's sp handling.
|
|
31
|
+
position + 2
|
|
32
|
+
else
|
|
33
|
+
position
|
|
34
|
+
end
|
|
35
|
+
msg("VM %s(%d) = %s" % [name, position,
|
|
36
|
+
@proc.frame.send(name, lookup_pos).inspect])
|
|
37
|
+
return position
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative '../../base/subsubcmd'
|
|
4
|
+
require_relative 'helper'
|
|
5
|
+
|
|
6
|
+
class Trepan::Subcommand::InfoRegistersLfp < Trepan::SubSubcommand
|
|
7
|
+
unless defined?(HELP)
|
|
8
|
+
HELP = 'Show the value of the VM local frame pointer (LFP).
|
|
9
|
+
|
|
10
|
+
When a local variable is defined for the first time, this stack
|
|
11
|
+
is pushed and the value for local variable is assigned to this stack entry.
|
|
12
|
+
|
|
13
|
+
See also "info register sp".'
|
|
14
|
+
|
|
15
|
+
MIN_ABBREV = 'lf'.size
|
|
16
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
17
|
+
NEED_STACK = true
|
|
18
|
+
PREFIX = %w(info registers lfp)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
include Registers
|
|
22
|
+
def run(args)
|
|
23
|
+
frame = @proc.frame
|
|
24
|
+
if 'CFUNC' == frame.type
|
|
25
|
+
msg "local_name not available for C function"
|
|
26
|
+
else
|
|
27
|
+
iseq = frame.iseq
|
|
28
|
+
index = register_array_index(PREFIX[-1], args, iseq.local_size-1)
|
|
29
|
+
msg("local_name(%d)=%s" % [index, iseq.local_name(index)]) if index
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
if __FILE__ == $0
|
|
35
|
+
# Demo it.
|
|
36
|
+
require_relative '../../../mock'
|
|
37
|
+
require_relative '../../../subcmd'
|
|
38
|
+
name = File.basename(__FILE__, '.rb')
|
|
39
|
+
|
|
40
|
+
# FIXME: DRY the below code
|
|
41
|
+
dbgr, info_cmd = MockDebugger::setup('info')
|
|
42
|
+
testcmdMgr = Trepan::Subcmd.new(info_cmd)
|
|
43
|
+
cmd_name = Trepan::SubSubcommand::InfoRegistersSp::PREFIX.join('')
|
|
44
|
+
infox_cmd = Trepan::SubSubcommand::InfoRegistersSp.new(info_cmd.proc,
|
|
45
|
+
info_cmd,
|
|
46
|
+
cmd_name)
|
|
47
|
+
# require_relative '../../../../lib/trepanning'
|
|
48
|
+
# dbgr = Trepan.new(:set_restart => true)
|
|
49
|
+
# dbgr.debugger
|
|
50
|
+
infox_cmd.run([])
|
|
51
|
+
|
|
52
|
+
# name = File.basename(__FILE__, '.rb')
|
|
53
|
+
# subcommand.summary_help(name)
|
|
54
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative '../../base/subsubcmd'
|
|
4
|
+
|
|
5
|
+
class Trepan::SubSubcommand::InfoRegistersPc < Trepan::SubSubcommand
|
|
6
|
+
unless defined?(HELP)
|
|
7
|
+
HELP = 'Show the value of the VM program counter (PC).
|
|
8
|
+
|
|
9
|
+
The VM program is an offset into the instruction sequence for the next
|
|
10
|
+
VM instruction in the sequence to be executed.
|
|
11
|
+
|
|
12
|
+
See also "info disassemble" and "info registers".'
|
|
13
|
+
MIN_ABBREV = 'pc'.size
|
|
14
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
15
|
+
NEED_STACK = true
|
|
16
|
+
PREFIX = %w(info registers pc)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def run(args)
|
|
20
|
+
msg("VM pc = %d" % @proc.frame.pc_offset)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
if __FILE__ == $0
|
|
25
|
+
# Demo it.
|
|
26
|
+
require_relative '../../../mock'
|
|
27
|
+
require_relative '../../../subcmd'
|
|
28
|
+
name = File.basename(__FILE__, '.rb')
|
|
29
|
+
|
|
30
|
+
# FIXME: DRY the below code
|
|
31
|
+
dbgr, info_cmd = MockDebugger::setup('info')
|
|
32
|
+
testcmdMgr = Trepan::Subcmd.new(info_cmd)
|
|
33
|
+
cmd_name = Trepan::SubSubcommand::InfoRegistersPc::PREFIX.join('')
|
|
34
|
+
infox_cmd = Trepan::SubSubcommand::InfoRegistersPc.new(info_cmd.proc,
|
|
35
|
+
info_cmd,
|
|
36
|
+
cmd_name)
|
|
37
|
+
# require_relative '../../../../trepanning'
|
|
38
|
+
# dbgr = Trepan.new(:set_restart => true)
|
|
39
|
+
# dbgr.debugger
|
|
40
|
+
infox_cmd.run([])
|
|
41
|
+
|
|
42
|
+
# name = File.basename(__FILE__, '.rb')
|
|
43
|
+
# subcommand.summary_help(name)
|
|
44
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative '../../base/subsubcmd'
|
|
4
|
+
require_relative 'helper'
|
|
5
|
+
|
|
6
|
+
class Trepan::Subcommand::InfoRegistersSp < Trepan::SubSubcommand
|
|
7
|
+
unless defined?(HELP)
|
|
8
|
+
HELP = 'Show information about the VM stack pointer (SP).
|
|
9
|
+
|
|
10
|
+
usage:
|
|
11
|
+
info register sp [NUMBER NUMBER ...|size]
|
|
12
|
+
|
|
13
|
+
With no arguments, all SP values for the current frame of the debugged
|
|
14
|
+
program are shown. If a number is given, then the entry at that
|
|
15
|
+
location is shown. If "size" is given, then we show the number items
|
|
16
|
+
in the stack of the current frame.
|
|
17
|
+
|
|
18
|
+
The VM uses a stack to store temporary values in computations. For
|
|
19
|
+
example to compute "a + b", the values of "a" and "b" are pushed onto
|
|
20
|
+
a stack pointed to by SP. Just before the addition is perofrmed, sp(1)
|
|
21
|
+
will have the value "a" contians and sp(2) will contain the value of
|
|
22
|
+
"b"
|
|
23
|
+
|
|
24
|
+
See also "info register LFP"'
|
|
25
|
+
|
|
26
|
+
MIN_ABBREV = 'sp'.size
|
|
27
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
28
|
+
NEED_STACK = true
|
|
29
|
+
PREFIX = %w(info registers sp)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
include Registers
|
|
33
|
+
def run(args)
|
|
34
|
+
if args.size == 0
|
|
35
|
+
1.upto(@proc.frame.sp_size-1) do |i|
|
|
36
|
+
msg "%s%d: %s" % [' ' * 2, i, @proc.frame.sp(i).inspect]
|
|
37
|
+
end if @proc.frame.sp_size
|
|
38
|
+
elsif args.size == 1 and 'size' == args[0]
|
|
39
|
+
msg "Number of stack items in frame is #{@proc.frame.sp_size}."
|
|
40
|
+
else
|
|
41
|
+
args.each do |arg|
|
|
42
|
+
register_array_index(PREFIX[-1], arg, @proc.frame.sp_size)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
if __FILE__ == $0
|
|
49
|
+
# Demo it.
|
|
50
|
+
require_relative '../../../mock'
|
|
51
|
+
require_relative '../../../subcmd'
|
|
52
|
+
name = File.basename(__FILE__, '.rb')
|
|
53
|
+
|
|
54
|
+
# FIXME: DRY the below code
|
|
55
|
+
dbgr, info_cmd = MockDebugger::setup('info')
|
|
56
|
+
testcmdMgr = Trepan::Subcmd.new(info_cmd)
|
|
57
|
+
cmd_name = Trepan::SubSubcommand::InfoRegistersSp::PREFIX.join('')
|
|
58
|
+
infox_cmd = Trepan::SubSubcommand::InfoRegistersSp.new(info_cmd.proc,
|
|
59
|
+
info_cmd,
|
|
60
|
+
cmd_name)
|
|
61
|
+
infox_cmd.summary_help(name)
|
|
62
|
+
puts
|
|
63
|
+
# require_relative '../../../../lib/trepanning'
|
|
64
|
+
# dbgr = Trepan.new(:set_restart => true)
|
|
65
|
+
# dbgr.debugger
|
|
66
|
+
infox_cmd.run([])
|
|
67
|
+
puts
|
|
68
|
+
%w(0 1 10).each do |val|
|
|
69
|
+
infox_cmd.run([val])
|
|
70
|
+
puts '-' * 40
|
|
71
|
+
end
|
|
72
|
+
infox_cmd.run(['size'])
|
|
73
|
+
|
|
74
|
+
name = File.basename(__FILE__, '.rb')
|
|
75
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative '../base/subcmd'
|
|
4
|
+
|
|
5
|
+
class Trepan::Subcommand::InfoReturn < Trepan::Subcommand
|
|
6
|
+
unless defined?(HELP)
|
|
7
|
+
HELP = 'Show the value about to be returned'
|
|
8
|
+
MIN_ABBREV = 'ret'.size # Note we have "info registers"
|
|
9
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
10
|
+
NEED_STACK = true
|
|
11
|
+
PREFIX = %w(info return)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def run(args)
|
|
15
|
+
event = @proc.event
|
|
16
|
+
if %w(return c-return).member?(event)
|
|
17
|
+
ret_val = Trepan::Frame.value_returned(@proc.frame, event)
|
|
18
|
+
msg('Return value: %s' % ret_val.inspect)
|
|
19
|
+
else
|
|
20
|
+
errmsg('You need to be in a return event to do this. Event is %s' %
|
|
21
|
+
event)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
if __FILE__ == $0
|
|
28
|
+
# Demo it.
|
|
29
|
+
require_relative '../../mock'
|
|
30
|
+
require_relative '../../subcmd'
|
|
31
|
+
name = File.basename(__FILE__, '.rb')
|
|
32
|
+
|
|
33
|
+
# FIXME: DRY the below code
|
|
34
|
+
dbgr, cmd = MockDebugger::setup('info')
|
|
35
|
+
subcommand = Trepan::Subcommand::InfoReturn.new(cmd)
|
|
36
|
+
testcmdMgr = Trepan::Subcmd.new(subcommand)
|
|
37
|
+
|
|
38
|
+
name = File.basename(__FILE__, '.rb')
|
|
39
|
+
subcommand.summary_help(name)
|
|
40
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative '../base/subcmd'
|
|
4
|
+
require_relative '../../../app/thread'
|
|
5
|
+
require_relative '../../../app/frame'
|
|
6
|
+
|
|
7
|
+
class Trepan::Subcommand::InfoThread < Trepan::Subcommand
|
|
8
|
+
unless defined?(HELP)
|
|
9
|
+
HELP =
|
|
10
|
+
'info thread [THREAD-ARG1 THREAD-ARG2.. ]
|
|
11
|
+
|
|
12
|
+
Show frame information for thread(s). If no thread arguments are
|
|
13
|
+
given, then the top frame information is shown for all threads.
|
|
14
|
+
|
|
15
|
+
If arguments are given, each number should be either the object id of
|
|
16
|
+
the thread, a position number in the list of threads, "M", or ".". The
|
|
17
|
+
object id and list position are given when "info thread" is run. The
|
|
18
|
+
name "M" in upper- or lower- case refers to the "main thread" and "."
|
|
19
|
+
refers to the current thread.
|
|
20
|
+
|
|
21
|
+
Examples:
|
|
22
|
+
info thread # Show summary frame information
|
|
23
|
+
info thread M # information for main thread
|
|
24
|
+
info thread . # information for current thread
|
|
25
|
+
info thread 1 2 m # information for thread in list 1, 2, and main
|
|
26
|
+
info thread 92562770 # ifnormation for thread with object id 92562770
|
|
27
|
+
'
|
|
28
|
+
MIN_ABBREV = 'thr'.size
|
|
29
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
30
|
+
NEED_STACK = true
|
|
31
|
+
PREFIX = %w(info thread)
|
|
32
|
+
SHORT_HELP = 'Show frame(s) for threads'
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
include Trepan::ThreadHelper
|
|
36
|
+
include Trepan::Frame # To show stack
|
|
37
|
+
|
|
38
|
+
def list_threads(verbose=false)
|
|
39
|
+
Thread.list.each_with_index do |th, i|
|
|
40
|
+
main_str =
|
|
41
|
+
if th == Thread.main
|
|
42
|
+
'(main thread) '
|
|
43
|
+
else
|
|
44
|
+
''
|
|
45
|
+
end
|
|
46
|
+
frame, line_no, mark =
|
|
47
|
+
if th == Thread.current
|
|
48
|
+
[@proc.frame, @proc.frame_line, '+']
|
|
49
|
+
else
|
|
50
|
+
[th.threadframe,
|
|
51
|
+
(@proc.frame.source_location && @proc.frame.source_location[0]),
|
|
52
|
+
' ']
|
|
53
|
+
end
|
|
54
|
+
frame_info = format_stack_call(frame, {})
|
|
55
|
+
|
|
56
|
+
source_container = @proc.frame_container(frame, false)
|
|
57
|
+
loc = @proc.source_location_info(source_container, line_no, frame)
|
|
58
|
+
|
|
59
|
+
msg("%s %2d %s%d %s\n\t%s\n\t%s" %
|
|
60
|
+
[mark, i, main_str, th.object_id, th.inspect, frame_info, loc])
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def run(args)
|
|
65
|
+
if args.size == 2
|
|
66
|
+
list_threads
|
|
67
|
+
elsif args.size > 2
|
|
68
|
+
args[2..-1].each do |id_or_num_str|
|
|
69
|
+
th = @proc.get_thread_from_string(id_or_num_str)
|
|
70
|
+
if th
|
|
71
|
+
frame = @proc.get_frame_from_thread(th)
|
|
72
|
+
print_stack_trace(frame, {:maxstack => settings[:maxstack]})
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
else
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
if __FILE__ == $0
|
|
82
|
+
# Demo it.
|
|
83
|
+
require_relative '../../mock'
|
|
84
|
+
name = File.basename(__FILE__, '.rb')
|
|
85
|
+
|
|
86
|
+
dbgr, cmd = MockDebugger::setup('info')
|
|
87
|
+
# FIXME: shouldn't have to do this:
|
|
88
|
+
cmd.proc.settings[:maxstring] = 150
|
|
89
|
+
|
|
90
|
+
name = File.basename(__FILE__, '.rb')
|
|
91
|
+
cmd_args = ['info', name]
|
|
92
|
+
|
|
93
|
+
cmd.proc.instance_variable_set('@last_args', cmd_args)
|
|
94
|
+
cmd_args = ['info', name]
|
|
95
|
+
cmd.proc.frame_setup(RubyVM::ThreadFrame::current)
|
|
96
|
+
cmd.run(cmd_args)
|
|
97
|
+
puts '-' * 20
|
|
98
|
+
Thread.new do
|
|
99
|
+
cmd.proc.frame_setup(RubyVM::ThreadFrame::current)
|
|
100
|
+
cmd.run(cmd_args)
|
|
101
|
+
puts '-' * 10
|
|
102
|
+
cmd.run(cmd_args + [0])
|
|
103
|
+
puts '-' * 10
|
|
104
|
+
cmd.run(cmd_args + [1])
|
|
105
|
+
end.join
|
|
106
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
2
|
+
require 'irb'
|
|
3
|
+
require_relative 'base/cmd'
|
|
4
|
+
require_relative '../../app/irb'
|
|
5
|
+
class Trepan::Command::IRBCommand < Trepan::Command
|
|
6
|
+
|
|
7
|
+
unless defined?(HELP)
|
|
8
|
+
HELP =
|
|
9
|
+
" irb [-d]\tstarts an Interactive Ruby (IRB) session.
|
|
10
|
+
|
|
11
|
+
If -d is added you can get access to debugger frame the global variables
|
|
12
|
+
$trepan_frame and $trepan_cmdproc.
|
|
13
|
+
|
|
14
|
+
irb is extended with methods 'cont', 'dbgr', 'n', and, 'q', 'step' which
|
|
15
|
+
run the corresponding debugger commands.
|
|
16
|
+
|
|
17
|
+
To issue a debugger command, inside irb nested inside a debugger use
|
|
18
|
+
'dbgr'. For example:
|
|
19
|
+
|
|
20
|
+
dbgr %%w(info program)
|
|
21
|
+
dbgr('info', 'program') # Same as above
|
|
22
|
+
dbgr 'info program' # Single quoted string also works
|
|
23
|
+
|
|
24
|
+
But arguments have to be quoted because irb will evaluate them:
|
|
25
|
+
|
|
26
|
+
dbgr info program # wrong!
|
|
27
|
+
dbgr info, program # wrong!
|
|
28
|
+
dbgr(info, program) # What I say 3 times is wrong!
|
|
29
|
+
|
|
30
|
+
Here then is a loop to query VM stack values:
|
|
31
|
+
(-1..1).each {|i| dbgr(\"info reg sp \#{i}\")}
|
|
32
|
+
"
|
|
33
|
+
|
|
34
|
+
CATEGORY = 'support'
|
|
35
|
+
MAX_ARGS = 1 # Need at most this many
|
|
36
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
37
|
+
SHORT_HELP = 'Run interactive Ruby session irb as a command subshell'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# This method runs the command
|
|
41
|
+
def run(args) # :nodoc
|
|
42
|
+
add_debugging =
|
|
43
|
+
if args.size > 1
|
|
44
|
+
'-d' == args[1]
|
|
45
|
+
else
|
|
46
|
+
false
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# unless @state.interface.kind_of?(LocalInterface)
|
|
50
|
+
# print "Command is available only in local mode.\n"
|
|
51
|
+
# throw :debug_error
|
|
52
|
+
# end
|
|
53
|
+
|
|
54
|
+
save_trap = trap('SIGINT') do
|
|
55
|
+
throw :IRB_EXIT, :cont if $trepan_in_irb
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
$trepan = @proc.dbgr
|
|
59
|
+
if add_debugging
|
|
60
|
+
$trepan_cmdproc = @proc
|
|
61
|
+
$trepan_frame = @proc.frame
|
|
62
|
+
end
|
|
63
|
+
$trepan_in_irb = true
|
|
64
|
+
$trepan_irb_statements = nil
|
|
65
|
+
$trepan_command = nil
|
|
66
|
+
|
|
67
|
+
conf = {:BACK_TRACE_LIMIT => settings[:maxstack]}
|
|
68
|
+
cont = IRB.start_session(@proc.frame.binding, @proc, conf)
|
|
69
|
+
trap('SIGINT', save_trap) # Restore old trap
|
|
70
|
+
|
|
71
|
+
back_trace_limit = IRB.CurrentContext.back_trace_limit
|
|
72
|
+
if settings[:maxstack] != back_trace_limit
|
|
73
|
+
msg("\nSetting debugger's BACK_TRACE_LIMIT (%d) to match irb's last setting (%d)" %
|
|
74
|
+
[settings[:maxstack], back_trace_limit])
|
|
75
|
+
settings[:maxstack]= IRB.CurrentContext.back_trace_limit
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
case cont
|
|
79
|
+
when :continue
|
|
80
|
+
@proc.continue
|
|
81
|
+
when :finish
|
|
82
|
+
@proc.finish
|
|
83
|
+
when :next
|
|
84
|
+
@proc.next # (1, {})
|
|
85
|
+
when :quit
|
|
86
|
+
@proc.quit
|
|
87
|
+
when :step
|
|
88
|
+
@proc.step # (1, {})
|
|
89
|
+
else
|
|
90
|
+
@proc.print_location
|
|
91
|
+
end
|
|
92
|
+
ensure
|
|
93
|
+
$trepan_in_irb = false
|
|
94
|
+
# restore old trap if any
|
|
95
|
+
trap('SIGINT', save_trap) if save_trap
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
if __FILE__ == $0
|
|
100
|
+
require 'thread_frame'
|
|
101
|
+
require_relative '../mock'
|
|
102
|
+
name = File.basename(__FILE__, '.rb')
|
|
103
|
+
dbgr, cmd = MockDebugger::setup(name)
|
|
104
|
+
# Get an IRB session -- the hard way :-)
|
|
105
|
+
cmd.run([name]) if ARGV.size > 0
|
|
106
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
2
|
+
require_relative 'base/cmd'
|
|
3
|
+
class Trepan::Command::KillCommand < Trepan::Command
|
|
4
|
+
|
|
5
|
+
unless defined?(HELP)
|
|
6
|
+
HELP =
|
|
7
|
+
"Kill execution of program being debugged.
|
|
8
|
+
|
|
9
|
+
Equivalent of Process.kill('KILL', Process.pid). This is an unmaskable
|
|
10
|
+
signal. When all else fails, e.g. in thread code, use this.
|
|
11
|
+
|
|
12
|
+
If 'unconditionally' is given, no questions are asked. Otherwise, if
|
|
13
|
+
we are in interactive mode, we'll prompt to make sure."
|
|
14
|
+
|
|
15
|
+
CATEGORY = 'running'
|
|
16
|
+
MAX_ARGS = 1 # Need at most this many
|
|
17
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
18
|
+
SHORT_HELP = 'Send this process a POSIX signal (default "9" is "kill -9")'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# This method runs the command
|
|
22
|
+
def run(args) # :nodoc
|
|
23
|
+
if args.size > 1
|
|
24
|
+
sig = Integer(args[1]) rescue args[1]
|
|
25
|
+
unless sig.is_a?(Integer) || Signal.list.member?(sig)
|
|
26
|
+
errmsg("Signal name '#{sig}' is not a signal I know about.\n")
|
|
27
|
+
return false
|
|
28
|
+
end
|
|
29
|
+
# FIXME: reinstate
|
|
30
|
+
# if 'KILL' == sig || Signal['KILL'] == sig
|
|
31
|
+
# @proc.intf.finalize
|
|
32
|
+
# end
|
|
33
|
+
else
|
|
34
|
+
if not confirm('Really kill?', false)
|
|
35
|
+
msg('Kill not confirmed.')
|
|
36
|
+
return
|
|
37
|
+
else
|
|
38
|
+
sig = 'KILL'
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
begin
|
|
42
|
+
Process.kill(sig, Process.pid)
|
|
43
|
+
rescue Errno::ESRCH
|
|
44
|
+
errmsg "Unable to send kill #{sig} to process #{Process.pid}"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if __FILE__ == $0
|
|
50
|
+
require_relative '../mock'
|
|
51
|
+
name = File.basename(__FILE__, '.rb')
|
|
52
|
+
dbgr, cmd = MockDebugger::setup(name)
|
|
53
|
+
%w(fooo 1 -1 HUP -9).each do |arg|
|
|
54
|
+
puts "#{name} #{arg}"
|
|
55
|
+
cmd.run([name, arg])
|
|
56
|
+
puts '=' * 40
|
|
57
|
+
end
|
|
58
|
+
end
|