rbx-trepanning 0.0.1-universal-rubinius
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 +376 -0
- data/LICENSE +25 -0
- data/NEWS +2 -0
- data/README.textile +28 -0
- data/Rakefile +165 -0
- data/THANKS +14 -0
- data/app/breakpoint.rb +218 -0
- data/app/breakpoint.rbc +3564 -0
- data/app/brkptmgr.rb +138 -0
- data/app/brkptmgr.rbc +2827 -0
- data/app/default.rb +61 -0
- data/app/default.rbc +1011 -0
- data/app/display.rb +35 -0
- data/app/display.rbc +968 -0
- data/app/frame.rb +98 -0
- data/app/frame.rbc +1808 -0
- data/app/irb.rb +112 -0
- data/app/irb.rbc +2111 -0
- data/app/iseq.rb +95 -0
- data/app/iseq.rbc +1801 -0
- data/app/method.rb +173 -0
- data/app/method.rbc +2492 -0
- data/app/mock.rb +13 -0
- data/app/mock.rbc +398 -0
- data/app/options.rb +123 -0
- data/app/options.rbc +2183 -0
- data/app/run.rb +86 -0
- data/app/run.rbc +1244 -0
- data/app/util.rb +49 -0
- data/app/util.rbc +1144 -0
- data/app/validate.rb +30 -0
- data/app/validate.rbc +676 -0
- data/bin/trepan.compiled.rbc +1043 -0
- data/bin/trepanx +63 -0
- data/bin/trepanx.compiled.rbc +985 -0
- data/interface/base_intf.rb +95 -0
- data/interface/base_intf.rbc +1742 -0
- data/interface/script.rb +104 -0
- data/interface/script.rbc +1642 -0
- data/interface/user.rb +91 -0
- data/interface/user.rbc +1418 -0
- data/io/base_io.rb +94 -0
- data/io/base_io.rbc +1404 -0
- data/io/input.rb +112 -0
- data/io/input.rbc +1979 -0
- data/io/null_output.rb +42 -0
- data/io/null_output.rbc +730 -0
- data/io/string_array.rb +156 -0
- data/io/string_array.rbc +2466 -0
- data/lib/trepanning.rb +398 -0
- data/lib/trepanning.rbc +6661 -0
- data/processor/breakpoint.rb +161 -0
- data/processor/command/alias.rb +55 -0
- data/processor/command/backtrace.rb +46 -0
- data/processor/command/base/cmd.rb +124 -0
- data/processor/command/base/subcmd.rb +213 -0
- data/processor/command/base/submgr.rb +179 -0
- data/processor/command/base/subsubcmd.rb +103 -0
- data/processor/command/base/subsubmgr.rb +184 -0
- data/processor/command/break.rb +100 -0
- data/processor/command/continue.rb +82 -0
- data/processor/command/delete.rb +30 -0
- data/processor/command/directory.rb +43 -0
- data/processor/command/disassemble.rb +103 -0
- data/processor/command/down.rb +54 -0
- data/processor/command/eval.rb +31 -0
- data/processor/command/exit.rb +58 -0
- data/processor/command/finish.rb +78 -0
- data/processor/command/frame.rb +89 -0
- data/processor/command/help.rb +146 -0
- data/processor/command/info.rb +28 -0
- data/processor/command/info_subcmd/breakpoints.rb +75 -0
- data/processor/command/info_subcmd/file.rb +153 -0
- data/processor/command/info_subcmd/method.rb +71 -0
- data/processor/command/info_subcmd/program.rb +59 -0
- data/processor/command/info_subcmd/variables.rb +40 -0
- data/processor/command/irb.rb +96 -0
- data/processor/command/kill.rb +70 -0
- data/processor/command/list.rb +296 -0
- data/processor/command/next.rb +66 -0
- data/processor/command/nexti.rb +59 -0
- data/processor/command/pr.rb +38 -0
- data/processor/command/ps.rb +40 -0
- data/processor/command/restart.rb +60 -0
- data/processor/command/set.rb +47 -0
- data/processor/command/set_subcmd/auto.rb +28 -0
- data/processor/command/set_subcmd/auto_subcmd/dis.rb +33 -0
- data/processor/command/set_subcmd/auto_subcmd/eval.rb +54 -0
- data/processor/command/set_subcmd/auto_subcmd/irb.rb +34 -0
- data/processor/command/set_subcmd/auto_subcmd/list.rb +34 -0
- data/processor/command/set_subcmd/basename.rb +26 -0
- data/processor/command/set_subcmd/debug.rb +27 -0
- data/processor/command/set_subcmd/debug_subcmd/dbgr.rb +36 -0
- data/processor/command/set_subcmd/debug_subcmd/skip.rb +23 -0
- data/processor/command/set_subcmd/debug_subcmd/step.rb +23 -0
- data/processor/command/set_subcmd/different.rb +60 -0
- data/processor/command/set_subcmd/hidelevel.rb +63 -0
- data/processor/command/set_subcmd/kernelstep.rb +61 -0
- data/processor/command/set_subcmd/max.rb +29 -0
- data/processor/command/set_subcmd/max_subcmd/list.rb +49 -0
- data/processor/command/set_subcmd/max_subcmd/stack.rb +50 -0
- data/processor/command/set_subcmd/max_subcmd/string.rb +54 -0
- data/processor/command/set_subcmd/max_subcmd/width.rb +49 -0
- data/processor/command/set_subcmd/substitute.rb +25 -0
- data/processor/command/set_subcmd/substitute_subcmd/path.rb +56 -0
- data/processor/command/set_subcmd/trace.rb +37 -0
- data/processor/command/set_subcmd/trace_subcmd/print.rb +57 -0
- data/processor/command/show.rb +27 -0
- data/processor/command/show_subcmd/alias.rb +43 -0
- data/processor/command/show_subcmd/args.rb +26 -0
- data/processor/command/show_subcmd/auto.rb +28 -0
- data/processor/command/show_subcmd/auto_subcmd/dis.rb +37 -0
- data/processor/command/show_subcmd/auto_subcmd/eval.rb +28 -0
- data/processor/command/show_subcmd/auto_subcmd/irb.rb +23 -0
- data/processor/command/show_subcmd/auto_subcmd/list.rb +22 -0
- data/processor/command/show_subcmd/basename.rb +22 -0
- data/processor/command/show_subcmd/debug.rb +27 -0
- data/processor/command/show_subcmd/debug_subcmd/dbgr.rb +21 -0
- data/processor/command/show_subcmd/debug_subcmd/skip.rb +22 -0
- data/processor/command/show_subcmd/debug_subcmd/step.rb +22 -0
- data/processor/command/show_subcmd/different.rb +27 -0
- data/processor/command/show_subcmd/hidelevel.rb +42 -0
- data/processor/command/show_subcmd/kernelstep.rb +37 -0
- data/processor/command/show_subcmd/max.rb +30 -0
- data/processor/command/show_subcmd/max_subcmd/list.rb +38 -0
- data/processor/command/show_subcmd/max_subcmd/stack.rb +36 -0
- data/processor/command/show_subcmd/max_subcmd/string.rb +42 -0
- data/processor/command/show_subcmd/max_subcmd/width.rb +37 -0
- data/processor/command/show_subcmd/trace.rb +29 -0
- data/processor/command/show_subcmd/trace_subcmd/print.rb +38 -0
- data/processor/command/source.rb +83 -0
- data/processor/command/step.rb +41 -0
- data/processor/command/tbreak.rb +19 -0
- data/processor/command/unalias.rb +44 -0
- data/processor/command/up.rb +87 -0
- data/processor/default.rb +56 -0
- data/processor/disassemble.rb +32 -0
- data/processor/eval.rb +96 -0
- data/processor/frame.rb +211 -0
- data/processor/help.rb +72 -0
- data/processor/hook.rb +133 -0
- data/processor/load_cmds.rb +101 -0
- data/processor/location.rb +128 -0
- data/processor/main.rb +394 -0
- data/processor/mock.rb +137 -0
- data/processor/msg.rb +28 -0
- data/processor/running.rb +230 -0
- data/processor/stepping.rb +115 -0
- data/processor/subcmd.rb +160 -0
- data/processor/validate.rb +355 -0
- data/test/data/enable.right +36 -0
- data/test/data/fname-with-blank.cmd +6 -0
- data/test/data/fname-with-blank.right +1 -0
- data/test/data/quit-Xdebug.right +3 -0
- data/test/data/quit.cmd +5 -0
- data/test/data/quit.right +0 -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 +112 -0
- data/test/functional/test-break-name.rb +52 -0
- data/test/functional/test-break.rb +51 -0
- data/test/functional/test-finish.rb +70 -0
- data/test/functional/test-fn_helper.rb +43 -0
- data/test/functional/test-list.rb +55 -0
- data/test/functional/test-next-bug.rb +49 -0
- data/test/functional/test-next.rb +101 -0
- data/test/functional/test-step.rb +272 -0
- data/test/functional/test-step2.rb +35 -0
- data/test/functional/test-tbreak.rb +41 -0
- data/test/integration/file-diff.rb +89 -0
- data/test/integration/helper.rb +78 -0
- data/test/integration/test-fname-with-blank.rb +12 -0
- data/test/integration/test-quit.rb +25 -0
- data/test/unit/cmd-helper.rb +46 -0
- data/test/unit/test-app-brkpt.rb +30 -0
- data/test/unit/test-app-brkptmgr.rb +51 -0
- data/test/unit/test-app-iseq.rb +49 -0
- data/test/unit/test-app-method.rb +54 -0
- data/test/unit/test-app-options.rb +61 -0
- data/test/unit/test-app-run.rb +16 -0
- data/test/unit/test-app-util.rb +28 -0
- data/test/unit/test-app-validate.rb +18 -0
- data/test/unit/test-base-subcmd.rb +61 -0
- data/test/unit/test-bin-trepanx.rb +48 -0
- data/test/unit/test-cmd-alias.rb +49 -0
- data/test/unit/test-cmd-break.rb +23 -0
- data/test/unit/test-cmd-exit.rb +27 -0
- data/test/unit/test-cmd-help.rb +101 -0
- data/test/unit/test-cmd-kill.rb +48 -0
- data/test/unit/test-intf-user.rb +46 -0
- data/test/unit/test-io-input.rb +27 -0
- data/test/unit/test-proc-eval.rb +37 -0
- data/test/unit/test-proc-frame.rb +79 -0
- data/test/unit/test-proc-help.rb +16 -0
- data/test/unit/test-proc-hook.rb +30 -0
- data/test/unit/test-proc-load_cmds.rb +41 -0
- data/test/unit/test-proc-location.rb +48 -0
- data/test/unit/test-proc-main.rb +96 -0
- data/test/unit/test-proc-validate.rb +91 -0
- data/test/unit/test-subcmd-help.rb +51 -0
- metadata +337 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
2
|
+
require 'rubygems'; require 'require_relative'
|
3
|
+
require_relative 'base/cmd'
|
4
|
+
class Trepan::Command::DirectoryCommand < Trepan::Command
|
5
|
+
|
6
|
+
unless defined?(HELP)
|
7
|
+
ALIASES = %w(dir)
|
8
|
+
CATEGORY = 'files'
|
9
|
+
MAX_ARGS = 1 # Need at most this many
|
10
|
+
NAME = File.basename(__FILE__, '.rb')
|
11
|
+
HELP = <<-HELP
|
12
|
+
Add directory DIR to beginning of search path for source files.
|
13
|
+
DIR can also be $cwd for the current working directory, or $cdir for the
|
14
|
+
directory in which the debugged file start.
|
15
|
+
With no argument, reset the search path to $cdir:$cwd, the default.
|
16
|
+
|
17
|
+
This command may be useful for debugging into Rubinius methods such as
|
18
|
+
kernel/common/module.rb if have the source code somewhere.
|
19
|
+
HELP
|
20
|
+
SHORT_HELP =
|
21
|
+
'Add directory DIR to beginning of search path for source files'
|
22
|
+
end
|
23
|
+
|
24
|
+
# This method runs the command
|
25
|
+
def run(args) # :nodoc
|
26
|
+
if args.size > 1
|
27
|
+
settings[:directory] = "#{args[1]}:#{settings[:directory]}"
|
28
|
+
msg "Source directories searched: #{settings[:directory]}"
|
29
|
+
else
|
30
|
+
if confirm('Reintialize source path to empty?', false)
|
31
|
+
settings[:directory] = '$cdir:$cwd'
|
32
|
+
msg 'Source directories searched: $cdir:$cwd'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
if __FILE__ == $0
|
39
|
+
require_relative '../mock'
|
40
|
+
dbgr, cmd = MockDebugger::setup
|
41
|
+
cmd.run([cmd.name])
|
42
|
+
cmd.run([cmd.name, '/tmp'])
|
43
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'rubygems'; require 'require_relative'
|
2
|
+
require_relative './base/cmd'
|
3
|
+
require_relative '../../app/iseq'
|
4
|
+
|
5
|
+
class Trepan::Command::DisassembleCommand < Trepan::Command
|
6
|
+
NAME = File.basename(__FILE__, '.rb')
|
7
|
+
ALIASES = %w(dis)
|
8
|
+
CATEGORY = 'data'
|
9
|
+
HELP = <<-HELP
|
10
|
+
#{NAME} [all|method]
|
11
|
+
|
12
|
+
Disassembles Rubinius VM instructions. By default, the bytecode for the
|
13
|
+
current line is disassembled only.
|
14
|
+
|
15
|
+
If a method name is given, disassemble just that method. If the
|
16
|
+
argument is 'all', the entire method is shown as bytecode.
|
17
|
+
|
18
|
+
Examples:
|
19
|
+
#{NAME} # dissasemble VM for current line
|
20
|
+
#{NAME} all # disassemble entire current method
|
21
|
+
#{NAME} [1,2].max # disassemble max method of Array
|
22
|
+
#{NAME} Object.is_a? # disassemble Object.is_a?
|
23
|
+
#{NAME} is_a? # same as above (probably)
|
24
|
+
|
25
|
+
HELP
|
26
|
+
|
27
|
+
NEED_STACK = true
|
28
|
+
SHORT_HELP = 'Show the bytecode for the current method'
|
29
|
+
|
30
|
+
def disassemble_method(cm)
|
31
|
+
frame_ip = (@proc.frame.method == cm) ? @proc.frame.next_ip : nil
|
32
|
+
lines = cm.lines
|
33
|
+
next_line_ip = 0
|
34
|
+
next_i = 1
|
35
|
+
cm.decode.each do |insn|
|
36
|
+
show_line =
|
37
|
+
if insn.ip >= next_line_ip
|
38
|
+
next_line_ip = lines.at(next_i+1)
|
39
|
+
line_no = lines.at(next_i)
|
40
|
+
next_i += 2
|
41
|
+
true
|
42
|
+
else
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
prefix = Trepanning::ISeq::disasm_prefix(insn.ip, frame_ip, cm)
|
47
|
+
str = "#{prefix} #{insn}"
|
48
|
+
if show_line
|
49
|
+
str +=
|
50
|
+
if insn.instance_variable_get('@comment')
|
51
|
+
' '
|
52
|
+
elsif str[-1..-1] !~/\s/
|
53
|
+
' '
|
54
|
+
else
|
55
|
+
''
|
56
|
+
end
|
57
|
+
str += "# line: #{line_no}"
|
58
|
+
end
|
59
|
+
msg str
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Run command.
|
64
|
+
def run(args)
|
65
|
+
if 1 == args.size
|
66
|
+
@proc.show_bytecode
|
67
|
+
elsif 'all' == args[1]
|
68
|
+
# FIXME: first msg is a section command.
|
69
|
+
msg "Bytecode for #{@proc.frame.vm_location.describe}"
|
70
|
+
disassemble_method(current_method)
|
71
|
+
else
|
72
|
+
cm = @proc.parse_method(args[1])
|
73
|
+
if cm
|
74
|
+
# FIXME: first msg is a section command.
|
75
|
+
msg "Bytecode for method #{args[1]}"
|
76
|
+
disassemble_method(cm.executable)
|
77
|
+
else
|
78
|
+
errmsg "Method #{args[1]} not found"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
if __FILE__ == $0
|
85
|
+
# Demo it.
|
86
|
+
require_relative '../mock'
|
87
|
+
dbgr, cmd = MockDebugger::setup
|
88
|
+
def foo(cmd)
|
89
|
+
puts "#{cmd.name}"
|
90
|
+
cmd.run([cmd.name])
|
91
|
+
puts '=' * 40
|
92
|
+
puts "#{cmd.name} all"
|
93
|
+
cmd.run([cmd.name, 'all'])
|
94
|
+
puts '=' * 40
|
95
|
+
p cmd.proc.frame.vm_location.describe
|
96
|
+
cmd.run([cmd.name, 'foo'])
|
97
|
+
puts '=' * 40
|
98
|
+
# require_relative '../../lib/trepanning'
|
99
|
+
# debugger
|
100
|
+
cmd.run([cmd.name, 'self.setup'])
|
101
|
+
end
|
102
|
+
foo(cmd)
|
103
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
3
|
+
require 'rubygems'; require 'require_relative'
|
4
|
+
require_relative 'up'
|
5
|
+
|
6
|
+
# Debugger "down" command. Is the same as the "up" command with the
|
7
|
+
# direction (set by DIRECTION) reversed.
|
8
|
+
class Trepan::Command::DownCommand < Trepan::Command::UpCommand
|
9
|
+
|
10
|
+
# Silence already initialized constant .. warnings
|
11
|
+
old_verbose = $VERBOSE
|
12
|
+
$VERBOSE = nil
|
13
|
+
HELP =
|
14
|
+
"d(own) [count]
|
15
|
+
|
16
|
+
Move the current frame down in the stack trace (to a newer frame). 0
|
17
|
+
is the most recent frame. If no count is given, move down 1.
|
18
|
+
|
19
|
+
See also 'up' and 'frame'.
|
20
|
+
"
|
21
|
+
|
22
|
+
ALIASES = %w(d)
|
23
|
+
NAME = File.basename(__FILE__, '.rb')
|
24
|
+
SHORT_HELP = 'Move frame in the direction of the caller of the last-selected frame'
|
25
|
+
$VERBOSE = old_verbose
|
26
|
+
|
27
|
+
def initialize(proc)
|
28
|
+
super
|
29
|
+
@direction = -1 # +1 for up.
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
if __FILE__ == $0
|
35
|
+
# Demo it.
|
36
|
+
require_relative '../mock'
|
37
|
+
dbgr, cmd = MockDebugger::setup
|
38
|
+
|
39
|
+
# def sep ; puts '=' * 40 end
|
40
|
+
# cmd.run [cmd.name]
|
41
|
+
# %w(-1 0 1 -2).each do |count|
|
42
|
+
# puts "#{cmd.name} #{count}"
|
43
|
+
# cmd.run([cmd.name, count])
|
44
|
+
# sep
|
45
|
+
# end
|
46
|
+
# def foo(cmd, cmd.name)
|
47
|
+
# puts "#{cmd.name}"
|
48
|
+
# cmd.run([cmd.name])
|
49
|
+
# sep
|
50
|
+
# puts "#{cmd.name} -1"
|
51
|
+
# cmd.run([cmd.name, '-1'])
|
52
|
+
# end
|
53
|
+
# foo(cmd, cmd.name)
|
54
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rubygems'; require 'require_relative'
|
2
|
+
require_relative './base/cmd'
|
3
|
+
|
4
|
+
class Trepan::Command::EvalCommand < Trepan::Command
|
5
|
+
|
6
|
+
CATEGORY = 'data'
|
7
|
+
HELP = <<-HELP
|
8
|
+
Run code in the context of the current frame.
|
9
|
+
|
10
|
+
The value of the expression is stored into a global variable so it
|
11
|
+
may be used again easily. The name of the global variable is printed
|
12
|
+
next to the inspect output of the value.
|
13
|
+
HELP
|
14
|
+
|
15
|
+
NAME = File.basename(__FILE__, '.rb')
|
16
|
+
NEED_STACK = true
|
17
|
+
SHORT_HELP = 'Run code in the current context'
|
18
|
+
def run(args)
|
19
|
+
@proc.debug_eval(@proc.cmd_argstr, @proc.settings[:maxstring])
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
if __FILE__ == $0
|
24
|
+
require_relative '../mock'
|
25
|
+
dbgr, cmd = MockDebugger::setup
|
26
|
+
arg_str = '1 + 2'
|
27
|
+
## cmd.proc.instance_variable_set('@cmd_argstr', arg_str)
|
28
|
+
dbgr.instance_variable_set('@cmd_argstr', arg_str)
|
29
|
+
|
30
|
+
## cmd.run([cmd.name, arg_str])
|
31
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
2
|
+
require 'rubygems'; require 'require_relative'
|
3
|
+
require_relative 'base/cmd'
|
4
|
+
class Trepan::Command::ExitCommand < Trepan::Command
|
5
|
+
|
6
|
+
unless defined?(HELP)
|
7
|
+
ALIASES = %w(quit q q! quit! exit!)
|
8
|
+
HELP =
|
9
|
+
'exit [exitcode] - hard exit of the debugged program.
|
10
|
+
|
11
|
+
The program being debugged is exited via exit!() which does not run
|
12
|
+
the Kernel at_exit finalizers. If a return code is given, that is the
|
13
|
+
return code passed to exit() - presumably the return code that will be
|
14
|
+
passed back to the OS. If no exit code is given, 0 is used.
|
15
|
+
|
16
|
+
If you are in interactive mode, you are prompted to confirm
|
17
|
+
quitting. However if you do not want to be prompted, add ! the end.
|
18
|
+
(vim/vi/ed users can use alias q!).
|
19
|
+
|
20
|
+
See also "kill".'
|
21
|
+
|
22
|
+
CATEGORY = 'support'
|
23
|
+
MAX_ARGS = 2 # Need at most this many
|
24
|
+
NAME = File.basename(__FILE__, '.rb')
|
25
|
+
SHORT_HELP = 'Exit program via "exit!()"'
|
26
|
+
end
|
27
|
+
|
28
|
+
# FIXME: Combine 'quit' and 'exit'. The only difference is
|
29
|
+
# whether exit! or exit is used.
|
30
|
+
|
31
|
+
# This method runs the command
|
32
|
+
def run(args) # :nodoc
|
33
|
+
unconditional =
|
34
|
+
if args.size > 1 && args[1] == 'unconditionally'
|
35
|
+
args.shift
|
36
|
+
true
|
37
|
+
elsif args[0][-1..-1] == '!'
|
38
|
+
true
|
39
|
+
else
|
40
|
+
false
|
41
|
+
end
|
42
|
+
unless unconditional || confirm('Really quit?', false)
|
43
|
+
msg('Quit not confirmed.')
|
44
|
+
return
|
45
|
+
end
|
46
|
+
exitrc = (args.size > 1) ? exitrc = Integer(args[1]) rescue 0 : 0
|
47
|
+
# No graceful way to stop threads...
|
48
|
+
# A little harsh, but for now let's go with this.
|
49
|
+
exit! exitrc
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
if __FILE__ == $0
|
54
|
+
require_relative '../mock'
|
55
|
+
dbgr, cmd = MockDebugger::setup
|
56
|
+
fork { cmd.run([cmd.name]) }
|
57
|
+
cmd.run([cmd.name, '10'])
|
58
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
3
|
+
require 'rubygems'; require 'require_relative'
|
4
|
+
require_relative 'base/cmd'
|
5
|
+
|
6
|
+
class Trepan::Command::FinishCommand < Trepan::Command
|
7
|
+
|
8
|
+
unless defined?(HELP)
|
9
|
+
NAME = File.basename(__FILE__, '.rb')
|
10
|
+
HELP = <<-HELP
|
11
|
+
#{NAME} [levels]
|
12
|
+
|
13
|
+
Continue execution until leaving the current function.
|
14
|
+
Sometimes this is called 'step out'.
|
15
|
+
|
16
|
+
When `levels' is specified, that many frame levels need to be
|
17
|
+
popped. The default is 1. Note that 'yield' and exceptions raised my
|
18
|
+
reduce the number of stack frames. Also, if a thread is switched, we
|
19
|
+
stop ignoring levels.
|
20
|
+
|
21
|
+
'next>' is similar in that it stops at a return, but it doesn't
|
22
|
+
guarantee the stack level is the same as or less than the current
|
23
|
+
one.
|
24
|
+
|
25
|
+
See the break command if you want to stop at a particular point in a
|
26
|
+
program. In general, '#{NAME}', 'step' and 'next' may slow a program down
|
27
|
+
while 'break' will have less overhead.
|
28
|
+
HELP
|
29
|
+
ALIASES = %w(fin)
|
30
|
+
CATEGORY = 'running'
|
31
|
+
# execution_set = ['Running']
|
32
|
+
MAX_ARGS = 1 # Need at most this many.
|
33
|
+
NEED_STACK = true
|
34
|
+
SHORT_HELP = 'Step to end of current method (step out)'
|
35
|
+
end
|
36
|
+
|
37
|
+
# This method runs the command
|
38
|
+
def run(args) # :nodoc
|
39
|
+
opts = {}
|
40
|
+
if args.size == 1
|
41
|
+
# Form is: "finish" which means "finish 1"
|
42
|
+
level_count = 0
|
43
|
+
else
|
44
|
+
count_str = args[1]
|
45
|
+
opts = {
|
46
|
+
:msg_on_error =>
|
47
|
+
"The '#{NAME}' command argument must eval to an integer. Got: %s" %
|
48
|
+
count_str,
|
49
|
+
:min_value => 1
|
50
|
+
}
|
51
|
+
count = @proc.get_an_int(count_str, opts)
|
52
|
+
return unless count
|
53
|
+
# step 1 is core.level_count = 0 or "stop next event"
|
54
|
+
level_count = count - 1
|
55
|
+
end
|
56
|
+
if 0 == level_count and %w(return c-return).member?(@proc.event)
|
57
|
+
errmsg "You are already at the requested return event."
|
58
|
+
else
|
59
|
+
@proc.finish(level_count, opts)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
if __FILE__ == $0
|
65
|
+
require_relative '../mock'
|
66
|
+
dbgr, cmd = MockDebugger::setup
|
67
|
+
[%W(#{cmd.name} 1), %w(fin 2-1), %w(n foo)].each do |c|
|
68
|
+
cmd.proc.leave_cmd_loop = false
|
69
|
+
result = cmd.run(c)
|
70
|
+
puts 'Run result: %s' % result
|
71
|
+
puts 'leave_cmd_loop: %s' % cmd.proc.leave_cmd_loop
|
72
|
+
end
|
73
|
+
[%w(fin), [cmd.name]].each do |c|
|
74
|
+
cmd.proc.leave_cmd_loop = false
|
75
|
+
result = cmd.run(c)
|
76
|
+
puts cmd.proc.different_pos
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'rubygems'; require 'require_relative'
|
2
|
+
require_relative './base/cmd'
|
3
|
+
|
4
|
+
class Trepan::Command::FrameCommand < Trepan::Command
|
5
|
+
CATEGORY = 'stack'
|
6
|
+
HELP = <<-HELP
|
7
|
+
frame [frame-number]
|
8
|
+
|
9
|
+
Change the current frame to frame `frame-number' if specified, or the
|
10
|
+
most-recent frame, 0, if no frame number specified.
|
11
|
+
|
12
|
+
A negative number indicates the position from the other or
|
13
|
+
least-recently-entered end. So 'frame -1' moves to the oldest frame.
|
14
|
+
Any variable or expression that evaluates to a number can be used as a
|
15
|
+
position, however due to parsing limitations, the position expression
|
16
|
+
has to be seen as a single blank-delimited parameter. That is, the
|
17
|
+
expression '(5*3)-1' is okay while '( (5 * 3) - 1 )' isn't.
|
18
|
+
|
19
|
+
Examples:
|
20
|
+
frame # Set current frame at the current stopping point
|
21
|
+
frame 0 # Same as above
|
22
|
+
frame 5-5 # Same as above. Note: no spaces allowed in expression 5-5
|
23
|
+
frame 1 # Move to frame 1. Same as: frame 0; up
|
24
|
+
frame -1 # The least-recent frame
|
25
|
+
|
26
|
+
See also 'up', 'down', and 'backtrace'.
|
27
|
+
HELP
|
28
|
+
NAME = File.basename(__FILE__, '.rb')
|
29
|
+
SHORT_HELP = 'Make a specific frame in the call stack the current frame'
|
30
|
+
|
31
|
+
def run(args)
|
32
|
+
|
33
|
+
if args.size == 1
|
34
|
+
# Form is: "frame" which means "frame 0"
|
35
|
+
position_str = '0'
|
36
|
+
elsif args.size == 2
|
37
|
+
# Form is: "frame position"
|
38
|
+
position_str = args[1]
|
39
|
+
# elsif args.size == 3
|
40
|
+
# # Form is: frame <position> <thread>
|
41
|
+
# name_or_id = args[1]
|
42
|
+
# thread_str = args[2]
|
43
|
+
# th = @proc.get_thread_from_string(thread_str)
|
44
|
+
# if th
|
45
|
+
# @proc.frame_setup(th.threadframe)
|
46
|
+
# return
|
47
|
+
# else
|
48
|
+
# # FIXME: Give suitable error message was given
|
49
|
+
# end
|
50
|
+
# else
|
51
|
+
# # Form should be: "frame thread" which means
|
52
|
+
# # "frame thread 0"
|
53
|
+
# position_str = '0'
|
54
|
+
# ## FIXME:
|
55
|
+
# ## @proc.find_and_set_debugged_frame(frame, thread_id)
|
56
|
+
end
|
57
|
+
|
58
|
+
stack_size = @proc.dbgr.vm_locations.size
|
59
|
+
if stack_size == 0
|
60
|
+
errmsg('No frames recorded.')
|
61
|
+
return false
|
62
|
+
end
|
63
|
+
opts={
|
64
|
+
:msg_on_error =>
|
65
|
+
"The '#{NAME}' command requires a frame number. Got: #{position_str}",
|
66
|
+
:min_value => -stack_size,
|
67
|
+
:max_value => stack_size-1
|
68
|
+
}
|
69
|
+
frame_num = @proc.get_an_int(position_str, opts)
|
70
|
+
return false unless frame_num
|
71
|
+
|
72
|
+
@proc.adjust_frame(frame_num, true)
|
73
|
+
return true
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
if __FILE__ == $0
|
78
|
+
# Demo it.
|
79
|
+
require_relative '../mock'
|
80
|
+
dbgr, cmd = MockDebugger::setup
|
81
|
+
|
82
|
+
# def sep ; puts '=' * 40 end
|
83
|
+
# %w(0 1 -2).each {|count| cmd.run([cmd.name, count]); sep }
|
84
|
+
# def foo(cmd, cmd.name)
|
85
|
+
# cmd.proc.frame_setup(RubyVM::ThreadFrame::current)
|
86
|
+
# %w(0 -1).each {|count| cmd.run([cmd.name, count]); sep }
|
87
|
+
# end
|
88
|
+
# foo(cmd, cmd.name)
|
89
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
2
|
+
require 'rubygems'; require 'require_relative'
|
3
|
+
require_relative 'base/cmd'
|
4
|
+
class Trepan::Command::HelpCommand < Trepan::Command
|
5
|
+
|
6
|
+
unless defined?(HELP)
|
7
|
+
HELP =
|
8
|
+
"help [command [subcommand]|expression]
|
9
|
+
|
10
|
+
Without argument, print the list of available debugger commands.
|
11
|
+
|
12
|
+
When an argument is given, it is first checked to see if it is command
|
13
|
+
name. 'help where' gives help on the 'where' debugger command.
|
14
|
+
|
15
|
+
If the environment variable $PAGER is defined, the file is
|
16
|
+
piped through that command. You'll notice this only for long help
|
17
|
+
output.
|
18
|
+
|
19
|
+
Some commands like 'info', 'set', and 'show' can accept an
|
20
|
+
additional subcommand to give help just about that particular
|
21
|
+
subcommand. For example 'help info line' give help about the
|
22
|
+
info line command.
|
23
|
+
|
24
|
+
See also 'examine' and 'whatis'.
|
25
|
+
"
|
26
|
+
|
27
|
+
|
28
|
+
ALIASES = %w(?)
|
29
|
+
CATEGORIES = {
|
30
|
+
'breakpoints' => 'Making the program stop at certain points',
|
31
|
+
'data' => 'Examining data',
|
32
|
+
'files' => 'Specifying and examining files',
|
33
|
+
'running' => 'Running the program',
|
34
|
+
'status' => 'Status inquiries',
|
35
|
+
'support' => 'Support facilities',
|
36
|
+
'stack' => 'Examining the call stack'
|
37
|
+
}
|
38
|
+
CATEGORY = 'support'
|
39
|
+
NAME = File.basename(__FILE__, '.rb')
|
40
|
+
NEED_STACK = false
|
41
|
+
SHORT_HELP = 'Print commands or give help for command(s)'
|
42
|
+
end
|
43
|
+
|
44
|
+
# List the command categories and a short description of each.
|
45
|
+
def list_categories
|
46
|
+
msg("Classes of commands:")
|
47
|
+
CATEGORIES.keys.sort.each do |cat|
|
48
|
+
msg("%-13s -- %s" % [cat, CATEGORIES[cat]])
|
49
|
+
end
|
50
|
+
final_msg = '
|
51
|
+
Type "help" followed by a class name for a list of commands in that class.
|
52
|
+
Type "help *" for the list of all commands.
|
53
|
+
Type "help REGEXP" for the list of commands matching /^#{REGEXP}/
|
54
|
+
Type "help CLASS *" for the list of all commands in class CLASS.
|
55
|
+
Type "help" followed by command name for full documentation.
|
56
|
+
'
|
57
|
+
msg(final_msg)
|
58
|
+
end
|
59
|
+
|
60
|
+
# This method runs the command
|
61
|
+
def run(args) # :nodoc
|
62
|
+
if args.size > 1
|
63
|
+
cmd_name = args[1]
|
64
|
+
if cmd_name == '*'
|
65
|
+
msg("All command names:")
|
66
|
+
msg columnize_commands(@proc.commands.keys.sort)
|
67
|
+
elsif CATEGORIES.member?(cmd_name)
|
68
|
+
show_category(args[1], args[2..-1])
|
69
|
+
elsif @proc.commands.member?(cmd_name) or @proc.aliases.member?(cmd_name)
|
70
|
+
real_name =
|
71
|
+
if @proc.commands.member?(cmd_name)
|
72
|
+
cmd_name
|
73
|
+
else
|
74
|
+
@proc.aliases[cmd_name]
|
75
|
+
end
|
76
|
+
cmd_obj = @proc.commands[real_name]
|
77
|
+
help_text =
|
78
|
+
cmd_obj.respond_to?(:help) ? cmd_obj.help(args) :
|
79
|
+
cmd_obj.class.const_get(:HELP)
|
80
|
+
if help_text
|
81
|
+
msg(help_text)
|
82
|
+
if cmd_obj.class.constants.member?('ALIASES') and
|
83
|
+
args.size == 2
|
84
|
+
msg "Aliases: #{cmd_obj.class.const_get(:ALIASES).join(', ')}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
else
|
88
|
+
matches = @proc.commands.keys.grep(/^#{cmd_name}/).sort rescue []
|
89
|
+
if matches.empty?
|
90
|
+
errmsg("No commands found matching /^#{cmd_name}/. Try \"help\".")
|
91
|
+
else
|
92
|
+
msg("Command names matching /^#{cmd_name}/:")
|
93
|
+
msg columnize_commands(matches.sort)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
else
|
97
|
+
list_categories
|
98
|
+
end
|
99
|
+
return false # Don't break out of cmd loop
|
100
|
+
end
|
101
|
+
|
102
|
+
# Show short help for all commands in `category'.
|
103
|
+
def show_category(category, args)
|
104
|
+
|
105
|
+
if args.size == 1 && args[0] == '*'
|
106
|
+
msg("Commands in class %s:" % category)
|
107
|
+
|
108
|
+
cmds = @proc.commands.keys.select do |cmd_name|
|
109
|
+
category == @proc.commands[cmd_name].category
|
110
|
+
end.sort
|
111
|
+
|
112
|
+
width = settings[:maxwidth]
|
113
|
+
return columnize_commands(cmds)
|
114
|
+
end
|
115
|
+
|
116
|
+
msg("%s." % CATEGORIES[category])
|
117
|
+
msg("List of commands:\n")
|
118
|
+
@proc.commands.keys.sort.each do |name|
|
119
|
+
next if category != @proc.commands[name].category
|
120
|
+
msg("%-13s -- %s" % [name, @proc.commands[name].short_help])
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
if __FILE__ == $0
|
126
|
+
# Demo it.
|
127
|
+
require_relative '../mock'
|
128
|
+
dbgr, cmd = MockDebugger::setup
|
129
|
+
|
130
|
+
cmd.run %W(#{cmd.name} help)
|
131
|
+
puts '=' * 40
|
132
|
+
cmd.run %w(#{cmd.name} *)
|
133
|
+
puts '=' * 40
|
134
|
+
cmd.run %w(#{cmd.name} fdafsasfda)
|
135
|
+
puts '=' * 40
|
136
|
+
cmd.run [cmd.name]
|
137
|
+
puts '=' * 40
|
138
|
+
cmd.run %W(#{cmd.name} support)
|
139
|
+
puts '=' * 40
|
140
|
+
cmd.run %W(#{cmd.name} support *)
|
141
|
+
|
142
|
+
puts '=' * 40
|
143
|
+
cmd.run %W(#{cmd.name} s.*)
|
144
|
+
puts '=' * 40
|
145
|
+
cmd.run %W(#{cmd.name} s<>)
|
146
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
3
|
+
require 'rubygems'; require 'require_relative'
|
4
|
+
require_relative 'base/submgr'
|
5
|
+
|
6
|
+
class Trepan::Command::InfoCommand < Trepan::SubcommandMgr
|
7
|
+
unless defined?(HELP)
|
8
|
+
HELP =
|
9
|
+
'Generic command for showing things about the program being debugged.
|
10
|
+
|
11
|
+
You can give unique prefix of the name of a subcommand to get
|
12
|
+
information about just that subcommand.
|
13
|
+
|
14
|
+
Type "info" for a list of "info" subcommands and what they do.
|
15
|
+
Type "help info *" for just a list of "info" subcommands.
|
16
|
+
'
|
17
|
+
|
18
|
+
ALIASES = %w(i)
|
19
|
+
CATEGORY = 'status'
|
20
|
+
NAME = File.basename(__FILE__, '.rb')
|
21
|
+
SHORT_HELP = 'Information about debugged program and its environment'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
if __FILE__ == $0
|
26
|
+
require_relative '../mock'
|
27
|
+
dbgr, cmd = MockDebugger::setup
|
28
|
+
end
|