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,182 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative 'subcmd'
|
|
4
|
+
require_relative '../../subcmd'
|
|
5
|
+
require_relative '../../help'
|
|
6
|
+
|
|
7
|
+
class Trepan::SubSubcommandMgr < Trepan::Subcommand
|
|
8
|
+
|
|
9
|
+
include Trepan::Help
|
|
10
|
+
|
|
11
|
+
unless defined?(CATEGORY)
|
|
12
|
+
CATEGORY = 'status'
|
|
13
|
+
MIN_ARGS = 0
|
|
14
|
+
MAX_ARGS = nil
|
|
15
|
+
NAME = '?' # FIXME: Need to define this, but should
|
|
16
|
+
# pick this up from class/file name.
|
|
17
|
+
NEED_STACK = false
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
attr_accessor :pname
|
|
21
|
+
attr_accessor :subcmds # Array of instantiated Trepan::Subcommand objects
|
|
22
|
+
|
|
23
|
+
# Initialize show subcommands. Note: instance variable name
|
|
24
|
+
# has to be setcmds ('set' + 'cmds') for subcommand completion
|
|
25
|
+
# to work.
|
|
26
|
+
# FIXME: do we need proc still?
|
|
27
|
+
def initialize(proc, parent)
|
|
28
|
+
name = obj_const(self, :NAME)
|
|
29
|
+
@name = name.to_sym
|
|
30
|
+
@subcmds = Trepan::Subcmd.new(self)
|
|
31
|
+
@parent = parent
|
|
32
|
+
@pname = parent.name
|
|
33
|
+
@proc = parent.proc
|
|
34
|
+
|
|
35
|
+
# Set class constant SHORT_HELP to be the first line of HELP
|
|
36
|
+
# unless it has been defined in the class already.
|
|
37
|
+
# The below was the simplest way I could find to do this since
|
|
38
|
+
# we are the super class but want to set the subclass's constant.
|
|
39
|
+
# defined? didn't seem to work here.
|
|
40
|
+
c = self.class.constants
|
|
41
|
+
self.class.const_set('SHORT_HELP',
|
|
42
|
+
self.class.const_get('HELP')) if
|
|
43
|
+
c.member?(:HELP) and !c.member?(:SHORT_HELP)
|
|
44
|
+
|
|
45
|
+
load_debugger_subsubcommands(name, self)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Create an instance of each of the debugger subcommands. Commands
|
|
49
|
+
# are found by importing files in the directory 'name' + 'sub'. Some
|
|
50
|
+
# files are excluded via an array set in initialize. For each of
|
|
51
|
+
# the remaining files, we import them and scan for class names
|
|
52
|
+
# inside those files and for each class name, we will create an
|
|
53
|
+
# instance of that class. The set of TrepanCommand class instances
|
|
54
|
+
# form set of possible debugger commands.
|
|
55
|
+
def load_debugger_subsubcommands(name, obj)
|
|
56
|
+
|
|
57
|
+
# Initialization
|
|
58
|
+
cmd_names = []
|
|
59
|
+
cmd_dir = File.dirname(__FILE__)
|
|
60
|
+
subcmd_dir = File.join(cmd_dir, '..', @pname + '_subcmd', name + '_subcmd')
|
|
61
|
+
files = Dir.glob(File.join(subcmd_dir, '*.rb'))
|
|
62
|
+
files.each do |rb|
|
|
63
|
+
cmd_names << name.capitalize + File.basename(rb, '.rb').capitalize
|
|
64
|
+
require rb
|
|
65
|
+
end if File.directory?(subcmd_dir)
|
|
66
|
+
|
|
67
|
+
subcommands = {}
|
|
68
|
+
cmd_names.each do |subname|
|
|
69
|
+
cmd_name = "#{pname}#{subname.downcase}"
|
|
70
|
+
subclass_name = "#{@pname.capitalize}#{subname}"
|
|
71
|
+
next unless
|
|
72
|
+
Trepan::SubSubcommand.constants.member?(subclass_name.to_sym)
|
|
73
|
+
cmd = self.instance_eval("Trepan::SubSubcommand::" + subclass_name +
|
|
74
|
+
".new(self, @parent, '#{cmd_name}')")
|
|
75
|
+
@subcmds.add(cmd, cmd_name)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Give help for a command which has subcommands. This can be
|
|
80
|
+
# called in several ways:
|
|
81
|
+
# help cmd
|
|
82
|
+
# help cmd subcmd
|
|
83
|
+
# help cmd commands
|
|
84
|
+
#
|
|
85
|
+
# Our shtick is to give help for the overall command only if
|
|
86
|
+
# subcommand or 'commands' is not given. If a subcommand is given and
|
|
87
|
+
# found, then specific help for that is given. If 'commands' is given
|
|
88
|
+
# we will list the all the subcommands.
|
|
89
|
+
def help(args)
|
|
90
|
+
if args.size <= 3
|
|
91
|
+
# "help cmd". Give the general help for the command part.
|
|
92
|
+
doc = self.class.const_get(:HELP)
|
|
93
|
+
if doc
|
|
94
|
+
return doc
|
|
95
|
+
else
|
|
96
|
+
errmsg('Sorry - author mess up. ' +
|
|
97
|
+
'No help registered for command' +
|
|
98
|
+
@name)
|
|
99
|
+
return nil
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
prefix = my_const(:PREFIX)
|
|
104
|
+
subcmd_name = args[prefix.size+1]
|
|
105
|
+
prefix_str = prefix.join(' ')
|
|
106
|
+
|
|
107
|
+
if '*' == subcmd_name
|
|
108
|
+
help_text = ["List of subcommands for '%s':" % prefix_str]
|
|
109
|
+
cmd_names = @subcmds.list.map{|c| c[prefix_str.size-1..-1]}
|
|
110
|
+
help_text << columnize_commands(cmd_names)
|
|
111
|
+
return help_text
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# "help cmd subcmd". Give help specific for that subcommand if
|
|
115
|
+
# the command matches uniquely, or show a list of matching
|
|
116
|
+
# subcommands
|
|
117
|
+
keyprefix_str = prefix.join('')
|
|
118
|
+
key_str = keyprefix_str + subcmd_name
|
|
119
|
+
cmd = @subcmds.lookup(key_str, false)
|
|
120
|
+
if cmd
|
|
121
|
+
doc = obj_const(cmd, :HELP)
|
|
122
|
+
if doc
|
|
123
|
+
return doc
|
|
124
|
+
else
|
|
125
|
+
errmsg('Sorry - author mess up. ' +
|
|
126
|
+
'No help registered for subcommand: ' +
|
|
127
|
+
subcmd_name + ', of command: ' +
|
|
128
|
+
@name)
|
|
129
|
+
return nil
|
|
130
|
+
end
|
|
131
|
+
else
|
|
132
|
+
matches = @subcmds.list.grep(/^#{key_str}/).sort
|
|
133
|
+
if matches.empty?
|
|
134
|
+
errmsg("No #{name} subcommands found matching /^#{subcmd_name}/. Try \"help #{@name}\".")
|
|
135
|
+
return nil
|
|
136
|
+
elsif 1 == matches.size
|
|
137
|
+
args[-1] = matches[0].to_s[keyprefix_str.size..-1]
|
|
138
|
+
help(args)
|
|
139
|
+
else
|
|
140
|
+
help_text = ["Subcommands of \"#{@name}\" matching /^#{subcmd_name}/:"]
|
|
141
|
+
help_text << columnize_commands(matches.sort)
|
|
142
|
+
return help_text
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def run(args)
|
|
148
|
+
args = @parent.last_args if args.size == 0
|
|
149
|
+
if args.size < 3 || args.size == 3 && args[-1] == '*'
|
|
150
|
+
summary_list(obj_const(self, :NAME), @subcmds)
|
|
151
|
+
return false
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
subcmd_prefix = args[0..2].join('')
|
|
155
|
+
# We were given: cmd subcmd ...
|
|
156
|
+
# Run that.
|
|
157
|
+
subcmd = @subcmds.lookup(subcmd_prefix)
|
|
158
|
+
if subcmd
|
|
159
|
+
subcmd.run(args[2..-1])
|
|
160
|
+
else
|
|
161
|
+
undefined_subcmd(obj_const(self, :PREFIX).join(' '), args[-1])
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
if __FILE__ == $0
|
|
168
|
+
# Demo it.
|
|
169
|
+
require_relative '../../mock'
|
|
170
|
+
dbgr = MockDebugger::MockDebugger.new
|
|
171
|
+
cmds = dbgr.core.processor.commands
|
|
172
|
+
cmd = cmds['info']
|
|
173
|
+
Trepan::SubSubcommandMgr.new(dbgr.core.processor, cmd)
|
|
174
|
+
puts cmd.help(%w(help info registers))
|
|
175
|
+
puts '=' * 40
|
|
176
|
+
puts cmd.help(%w(help info registers *))
|
|
177
|
+
puts '=' * 40
|
|
178
|
+
# FIXME
|
|
179
|
+
# require_relative '../../lib/trepanning'
|
|
180
|
+
# Trepan.debug(:set_restart => true)
|
|
181
|
+
# puts cmd.help(%w(help info registers p.*))
|
|
182
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
2
|
+
require_relative 'base/cmd'
|
|
3
|
+
require_relative '../breakpoint'
|
|
4
|
+
require_relative '../../app/breakpoint'
|
|
5
|
+
class Trepan::Command::BreakCommand < Trepan::Command
|
|
6
|
+
|
|
7
|
+
unless defined?(HELP)
|
|
8
|
+
HELP =
|
|
9
|
+
'break [line number|offset]
|
|
10
|
+
|
|
11
|
+
With a line number argument, set a break there in the current
|
|
12
|
+
instruction sequence. With an offset (a number prefaced with an "O")
|
|
13
|
+
set a breakpoint at that instruction offset.
|
|
14
|
+
|
|
15
|
+
Examples:
|
|
16
|
+
break
|
|
17
|
+
break 10 # set breakpoint on line 10
|
|
18
|
+
break o20 # set breakpoint VM Instruction Sequence offset 20
|
|
19
|
+
'
|
|
20
|
+
|
|
21
|
+
ALIASES = %w(b)
|
|
22
|
+
CATEGORY = 'breakpoints'
|
|
23
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
24
|
+
SHORT_HELP = 'Set a breakpoint'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# This method runs the command
|
|
28
|
+
def run(args) # :nodoc
|
|
29
|
+
# FIXME: handle more conditions
|
|
30
|
+
# a line number
|
|
31
|
+
if args.size == 1
|
|
32
|
+
# usage is "break" which means break right here
|
|
33
|
+
# FIXME: should handle condition
|
|
34
|
+
bp = @proc.breakpoint_offset(@proc.frame.pc_offset,
|
|
35
|
+
@proc.frame.iseq)
|
|
36
|
+
else
|
|
37
|
+
position, iseq, use_offset, condition, name =
|
|
38
|
+
@proc.breakpoint_position(args[1..-1])
|
|
39
|
+
return false unless position && iseq
|
|
40
|
+
bp =
|
|
41
|
+
if use_offset
|
|
42
|
+
@proc.breakpoint_offset(position, iseq)
|
|
43
|
+
else
|
|
44
|
+
@proc.breakpoint_line(position, iseq)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
if bp
|
|
48
|
+
bp.condition = condition
|
|
49
|
+
|
|
50
|
+
mess = "Breakpoint %d set at " % bp.id
|
|
51
|
+
|
|
52
|
+
line_loc = "line %s in %s" %
|
|
53
|
+
[bp.source_location.join(', '),
|
|
54
|
+
@proc.canonic_container(bp.iseq.source_container).join(' ')]
|
|
55
|
+
|
|
56
|
+
vm_loc = "VM offset %d of instruction sequence \"%s\"" %
|
|
57
|
+
[bp.offset, bp.iseq.name]
|
|
58
|
+
|
|
59
|
+
loc, other_loc =
|
|
60
|
+
if 'line' == bp.type
|
|
61
|
+
[line_loc, vm_loc]
|
|
62
|
+
else # 'offset' == bp.type
|
|
63
|
+
[vm_loc, line_loc]
|
|
64
|
+
end
|
|
65
|
+
msg(mess + loc + ",\n\t" + other_loc + ".")
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
if __FILE__ == $0
|
|
71
|
+
require_relative '../mock'
|
|
72
|
+
name = File.basename(__FILE__, '.rb')
|
|
73
|
+
dbgr, cmd = MockDebugger::setup(name)
|
|
74
|
+
cmd.run([name])
|
|
75
|
+
cmd.run([name, __LINE__.to_s])
|
|
76
|
+
require 'thread_frame'
|
|
77
|
+
tf = RubyVM::ThreadFrame.current
|
|
78
|
+
pc_offset = tf.pc_offset
|
|
79
|
+
cmd.run([name, "O#{pc_offset}"])
|
|
80
|
+
def foo
|
|
81
|
+
5
|
|
82
|
+
end
|
|
83
|
+
cmd.run([name, 'foo', (__LINE__-2).to_s])
|
|
84
|
+
cmd.run([name, 'foo'])
|
|
85
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative 'base/cmd'
|
|
4
|
+
require_relative '../breakpoint'
|
|
5
|
+
require_relative '../../app/breakpoint'
|
|
6
|
+
require_relative '../../app/condition'
|
|
7
|
+
|
|
8
|
+
class Trepan::Command::ConditionCommand < Trepan::Command
|
|
9
|
+
|
|
10
|
+
unless defined?(HELP)
|
|
11
|
+
HELP =
|
|
12
|
+
'condition BP_NUMBER CONDITION
|
|
13
|
+
|
|
14
|
+
BP_NUMBER is a breakpoint number. CONDITION is an expression which
|
|
15
|
+
must evaluate to True before the breakpoint is honored. If CONDITION
|
|
16
|
+
is absent, any existing condition is removed; i.e., the breakpoint is
|
|
17
|
+
made unconditional.
|
|
18
|
+
|
|
19
|
+
Examples:
|
|
20
|
+
condition 5 x > 10 # Breakpoint 5 now has condition x > 10
|
|
21
|
+
condition 5 # Remove above condition
|
|
22
|
+
'
|
|
23
|
+
|
|
24
|
+
ALIASES = %w(cond)
|
|
25
|
+
CATEGORY = 'breakpoints'
|
|
26
|
+
MIN_ARGS = 1
|
|
27
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
28
|
+
NEED_STACK = false
|
|
29
|
+
SHORT_HELP = 'Specify breakpoint number N to break only if COND is true'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
include Trepan::Condition
|
|
33
|
+
|
|
34
|
+
def run(args)
|
|
35
|
+
bpnum = @proc.get_an_int(args[1])
|
|
36
|
+
bp = @proc.breakpoint_find(bpnum)
|
|
37
|
+
return unless bp
|
|
38
|
+
|
|
39
|
+
if args.size > 2
|
|
40
|
+
condition = args[2..-1].join(' ')
|
|
41
|
+
return unless valid_condition?(condition)
|
|
42
|
+
else
|
|
43
|
+
condition = 'true'
|
|
44
|
+
msg('Breakpoint %d is now unconditional.' % bp.id)
|
|
45
|
+
end
|
|
46
|
+
bp.condition = condition
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if __FILE__ == $0
|
|
51
|
+
require 'thread_frame'
|
|
52
|
+
require_relative '../mock'
|
|
53
|
+
name = File.basename(__FILE__, '.rb')
|
|
54
|
+
dbgr, cmd = MockDebugger::setup(name)
|
|
55
|
+
cmd.proc.frame_setup(RubyVM::ThreadFrame::current)
|
|
56
|
+
|
|
57
|
+
cmd.run([name, '1'])
|
|
58
|
+
cmdproc = dbgr.core.processor
|
|
59
|
+
cmds = cmdproc.commands
|
|
60
|
+
break_cmd = cmds['break']
|
|
61
|
+
break_cmd.run(['break', cmdproc.frame.source_location[0].to_s])
|
|
62
|
+
cmd.run([name, '1', 'x' '>' '10'])
|
|
63
|
+
cmd.run([name, '1'])
|
|
64
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
2
|
+
require_relative 'base/cmd'
|
|
3
|
+
require_relative '../running'
|
|
4
|
+
require_relative '../../app/breakpoint' # FIXME: possibly temporary
|
|
5
|
+
class Trepan::Command::ContinueCommand < Trepan::Command
|
|
6
|
+
|
|
7
|
+
unless defined?(HELP)
|
|
8
|
+
HELP =
|
|
9
|
+
'continue [offset|line number]
|
|
10
|
+
|
|
11
|
+
Leave the debugger loop and continue execution. Subsequent entry to
|
|
12
|
+
the debugger however may occur via breakpoints or explicit calls, or
|
|
13
|
+
exceptions.
|
|
14
|
+
|
|
15
|
+
If a parameter is given, a temporary breakpoint is set at that position
|
|
16
|
+
before continuing. Offset are numbers preficed with an "O" otherwise
|
|
17
|
+
the parameter is taken as a line number.
|
|
18
|
+
|
|
19
|
+
Examples:
|
|
20
|
+
continue
|
|
21
|
+
continue 10 # continue to line 10
|
|
22
|
+
continue o20 # continue to VM Instruction Sequence offset 20
|
|
23
|
+
'
|
|
24
|
+
|
|
25
|
+
ALIASES = %w(c)
|
|
26
|
+
CATEGORY = 'running'
|
|
27
|
+
MAX_ARGS = 1 # Need at most this many
|
|
28
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
29
|
+
NEED_RUNNING = true
|
|
30
|
+
SHORT_HELP = 'Continue execution of debugged program'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# This method runs the command
|
|
34
|
+
def run(args) # :nodoc
|
|
35
|
+
if args.size == 1
|
|
36
|
+
# Form is: "continue"
|
|
37
|
+
@proc.continue
|
|
38
|
+
else
|
|
39
|
+
# FIXME: handle more general condition parameter rather than just
|
|
40
|
+
# a line number
|
|
41
|
+
position, iseq, use_offset, condition =
|
|
42
|
+
@proc.breakpoint_position(args[1..-1])
|
|
43
|
+
return false unless position && iseq
|
|
44
|
+
bp =
|
|
45
|
+
if use_offset
|
|
46
|
+
@proc.breakpoint_offset(position, iseq, true)
|
|
47
|
+
else
|
|
48
|
+
@proc.breakpoint_line(position, iseq, true)
|
|
49
|
+
end
|
|
50
|
+
return unless bp
|
|
51
|
+
@proc.continue
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
if __FILE__ == $0
|
|
57
|
+
require_relative '../mock'
|
|
58
|
+
name = File.basename(__FILE__, '.rb')
|
|
59
|
+
dbgr, cmd = MockDebugger::setup(name)
|
|
60
|
+
p cmd.run([name])
|
|
61
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require 'thread_frame'
|
|
4
|
+
require_relative 'base/cmd'
|
|
5
|
+
|
|
6
|
+
class Trepan::Command::DebugCommand < Trepan::Command
|
|
7
|
+
unless defined?(HELP)
|
|
8
|
+
HELP =
|
|
9
|
+
"debug RUBY-CODE
|
|
10
|
+
|
|
11
|
+
Enter the debugger recursively on RUBY-CODE."
|
|
12
|
+
|
|
13
|
+
CATEGORY = 'data'
|
|
14
|
+
MIN_ARGS = 1
|
|
15
|
+
MAX_ARG = nil
|
|
16
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
17
|
+
NEED_STACK = false
|
|
18
|
+
SHORT_HELP = 'recursive debugging of an expression'
|
|
19
|
+
|
|
20
|
+
EXTRA_DEBUG_SETUP_CALLS = 4
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def run(args)
|
|
24
|
+
th = Thread.current
|
|
25
|
+
frame = @proc.frame # gets messed up in recursive call
|
|
26
|
+
arg_str = args[1..-1].join(' ')
|
|
27
|
+
hidelevels = @proc.hidelevels[th]
|
|
28
|
+
|
|
29
|
+
stack_diff = RubyVM::ThreadFrame.current.stack_size - frame.stack_size
|
|
30
|
+
|
|
31
|
+
# Ignore tracing in support routines:
|
|
32
|
+
tf = @proc.dbgr.trace_filter
|
|
33
|
+
[self.method(:run), @proc.method(:debug_eval),
|
|
34
|
+
@proc.method(:debug_eval_with_exception),
|
|
35
|
+
@proc.method(:get_binding_and_filename),
|
|
36
|
+
@proc.method(:fake_eval_filename)].each do |m|
|
|
37
|
+
tf << m unless tf.member?(m)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
@proc.hidelevels[th] += stack_diff + EXTRA_DEBUG_SETUP_CALLS
|
|
41
|
+
|
|
42
|
+
# Values we need to save before munging them
|
|
43
|
+
old_tracing = th.tracing
|
|
44
|
+
old_exec_event_tracing = th.exec_event_tracing
|
|
45
|
+
old_mutex = @proc.core.mutex
|
|
46
|
+
old_next_level = @proc.next_level
|
|
47
|
+
old_step_count = @proc.core.step_count
|
|
48
|
+
|
|
49
|
+
msg 'ENTERING NESTED DEBUGGER'
|
|
50
|
+
|
|
51
|
+
# Things we need to do to allow entering the debugger again
|
|
52
|
+
@proc.debug_nest += 1
|
|
53
|
+
@proc.core.mutex = Mutex.new
|
|
54
|
+
th.tracing = false
|
|
55
|
+
th.exec_event_tracing = false
|
|
56
|
+
@proc.core.step_count = 0
|
|
57
|
+
@proc.next_level = 32000
|
|
58
|
+
|
|
59
|
+
RubyVM::ThreadFrame.current.trace_off = false
|
|
60
|
+
retval = @proc.debug_eval(arg_str)
|
|
61
|
+
|
|
62
|
+
# Restore munged values
|
|
63
|
+
th.exec_event_tracing = old_exec_event_tracing
|
|
64
|
+
th.tracing = old_tracing
|
|
65
|
+
@proc.core.mutex = old_mutex
|
|
66
|
+
@proc.frame_setup(frame)
|
|
67
|
+
@proc.hidelevels[th] = hidelevels
|
|
68
|
+
@proc.core.step_count = old_step_count
|
|
69
|
+
@proc.next_level = old_next_level
|
|
70
|
+
@proc.print_location
|
|
71
|
+
@proc.debug_nest -= 1
|
|
72
|
+
msg 'LEAVING NESTED DEBUGGER'
|
|
73
|
+
msg "R=> #{retval.inspect}"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
if __FILE__ == $0
|
|
78
|
+
require_relative '../mock'
|
|
79
|
+
name = File.basename(__FILE__, '.rb')
|
|
80
|
+
dbgr, cmd = MockDebugger::setup(name)
|
|
81
|
+
name = File.basename(__FILE__, '.rb')
|
|
82
|
+
cmd.proc.hidelevels[Thread.current] = 0
|
|
83
|
+
cmd.proc.frame_setup(RubyVM::ThreadFrame::current)
|
|
84
|
+
cmd.run([name, 'x = 1; y = 2'])
|
|
85
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative 'base/cmd'
|
|
4
|
+
require_relative '../breakpoint'
|
|
5
|
+
require_relative '../../app/breakpoint'
|
|
6
|
+
class Trepan::Command::DeleteCommand < Trepan::Command
|
|
7
|
+
|
|
8
|
+
unless defined?(HELP)
|
|
9
|
+
HELP =
|
|
10
|
+
'delete [bpnumber [bpnumber...]] - Delete some breakpoints.
|
|
11
|
+
|
|
12
|
+
Arguments are breakpoint numbers with spaces in between. To delete
|
|
13
|
+
all breakpoints, give no argument. those breakpoints. Without
|
|
14
|
+
argument, clear all breaks (but first ask confirmation).
|
|
15
|
+
|
|
16
|
+
See also the "clear" command which clears breakpoints by line/file
|
|
17
|
+
number.
|
|
18
|
+
'
|
|
19
|
+
|
|
20
|
+
CATEGORY = 'breakpoints'
|
|
21
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
22
|
+
SHORT_HELP = 'Delete some breakpoints'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def run(args)
|
|
26
|
+
if args.size == 1
|
|
27
|
+
if confirm('Delete all breakpoints?', false)
|
|
28
|
+
@proc.brkpts.reset
|
|
29
|
+
return
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
first = args.shift
|
|
33
|
+
args.each do |num_str|
|
|
34
|
+
i = @proc.get_an_int(num_str)
|
|
35
|
+
success = @proc.delete_breakpoint_by_number(num_str.to_i, false) if i
|
|
36
|
+
msg('Deleted breakpoint %d.' % i) if success
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
if __FILE__ == $0
|
|
42
|
+
require_relative '../mock'
|
|
43
|
+
name = File.basename(__FILE__, '.rb')
|
|
44
|
+
dbgr, cmd = MockDebugger::setup(name)
|
|
45
|
+
cmd.run([name])
|
|
46
|
+
cmd.run([name, '1'])
|
|
47
|
+
cmdproc = dbgr.core.processor
|
|
48
|
+
cmds = dbgr.core.processor.commands
|
|
49
|
+
break_cmd = cmds['break']
|
|
50
|
+
break_cmd.run(['break', cmdproc.frame.source_location[0].to_s])
|
|
51
|
+
# require_relative '../../lib/trepanning'
|
|
52
|
+
# Trepan.debug(:set_restart => true)
|
|
53
|
+
cmd.run([name, '1'])
|
|
54
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
2
|
+
require_relative 'base/cmd'
|
|
3
|
+
class Trepan::Command::DirectoryCommand < Trepan::Command
|
|
4
|
+
|
|
5
|
+
unless defined?(HELP)
|
|
6
|
+
ALIASES = %w(dir)
|
|
7
|
+
CATEGORY = 'files'
|
|
8
|
+
MAX_ARGS = 1 # Need at most this many
|
|
9
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
10
|
+
HELP = <<-HELP
|
|
11
|
+
Add directory DIR to beginning of search path for source files.
|
|
12
|
+
DIR can also be $cwd for the current working directory, or $cdir for the
|
|
13
|
+
directory in which the debugged file start.
|
|
14
|
+
With no argument, reset the search path to $cdir:$cwd, the default.
|
|
15
|
+
|
|
16
|
+
This command may be useful for debugging into Rubinius methods such as
|
|
17
|
+
kernel/common/module.rb if have the source code somewhere.
|
|
18
|
+
HELP
|
|
19
|
+
SHORT_HELP =
|
|
20
|
+
'Add directory DIR to beginning of search path for source files'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# This method runs the command
|
|
24
|
+
def run(args) # :nodoc
|
|
25
|
+
if args.size > 1
|
|
26
|
+
settings[:directory] = "#{args[1]}:#{settings[:directory]}"
|
|
27
|
+
msg "Source directories searched: #{settings[:directory]}"
|
|
28
|
+
else
|
|
29
|
+
if confirm('Reintialize source path to empty?', false)
|
|
30
|
+
settings[:directory] = '$cdir:$cwd'
|
|
31
|
+
msg 'Source directories searched: $cdir:$cwd'
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
if __FILE__ == $0
|
|
38
|
+
require_relative '../mock'
|
|
39
|
+
name = File.basename(__FILE__, '.rb')
|
|
40
|
+
dbgr, cmd = MockDebugger::setup(name)
|
|
41
|
+
cmd.run([name])
|
|
42
|
+
cmd.run([name, '/tmp'])
|
|
43
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
|
3
|
+
require_relative 'base/cmd'
|
|
4
|
+
require_relative '../breakpoint'
|
|
5
|
+
require_relative '../../app/breakpoint'
|
|
6
|
+
|
|
7
|
+
# disable breakpoint command. The difference however is that the
|
|
8
|
+
# parameter to @proc.en_disable_breakpoint_by_number is different (set
|
|
9
|
+
# as ENABLE_PARM below).
|
|
10
|
+
#
|
|
11
|
+
# NOTE: The enable command subclasses this, so beware when changing!
|
|
12
|
+
class Trepan::Command::DisableCommand < Trepan::Command
|
|
13
|
+
|
|
14
|
+
# Silence already initialized constant .. warnings
|
|
15
|
+
old_verbose = $VERBOSE
|
|
16
|
+
$VERBOSE = nil
|
|
17
|
+
HELP =
|
|
18
|
+
'disable [display] bpnumber [bpnumber ...]
|
|
19
|
+
|
|
20
|
+
Disables the breakpoints given as a space separated list of breakpoint
|
|
21
|
+
numbers. See also "info break" to get a list.
|
|
22
|
+
'
|
|
23
|
+
|
|
24
|
+
CATEGORY = 'breakpoints'
|
|
25
|
+
NAME = File.basename(__FILE__, '.rb')
|
|
26
|
+
SHORT_HELP = 'Disable some breakpoints'
|
|
27
|
+
|
|
28
|
+
$VERBOSE = old_verbose
|
|
29
|
+
|
|
30
|
+
def initialize(proc)
|
|
31
|
+
super
|
|
32
|
+
@enable_parm = false # true if enable
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def run(args)
|
|
36
|
+
if args.size == 1
|
|
37
|
+
errmsg('No breakpoint number given.')
|
|
38
|
+
return
|
|
39
|
+
end
|
|
40
|
+
# if args[1] == 'display'
|
|
41
|
+
# display_enable(args[2:], 0)
|
|
42
|
+
# end
|
|
43
|
+
first = args.shift
|
|
44
|
+
args.each do |num_str|
|
|
45
|
+
i = @proc.get_an_int(num_str)
|
|
46
|
+
success = @proc.en_disable_breakpoint_by_number(i, @enable_parm) if i
|
|
47
|
+
msg("Breakpoint %s #{@name}d." % i) if success
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
if __FILE__ == $0
|
|
53
|
+
require_relative '../mock'
|
|
54
|
+
name = File.basename(__FILE__, '.rb')
|
|
55
|
+
dbgr, cmd = MockDebugger::setup(name)
|
|
56
|
+
cmd.run([name])
|
|
57
|
+
cmd.run([name, '1'])
|
|
58
|
+
cmdproc = dbgr.core.processor
|
|
59
|
+
cmds = cmdproc.commands
|
|
60
|
+
break_cmd = cmds['break']
|
|
61
|
+
break_cmd.run(['break', cmdproc.frame.source_location[0].to_s])
|
|
62
|
+
# require_relative '../../lib/trepanning'
|
|
63
|
+
# Trepan.debug(:set_restart => true)
|
|
64
|
+
cmd.run([name, '1'])
|
|
65
|
+
end
|