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,355 @@
|
|
1
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
2
|
+
|
3
|
+
# Trepan command input validation routines. A String type is
|
4
|
+
# usually passed in as the argument to validation routines.
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'require_relative'
|
8
|
+
require 'linecache'
|
9
|
+
require_relative '../app/method'
|
10
|
+
require_relative '../app/validate'
|
11
|
+
## require_relative '../app/condition'
|
12
|
+
## require_relative '../app/file'
|
13
|
+
class Trepan
|
14
|
+
class CmdProcessor
|
15
|
+
|
16
|
+
attr_reader :dbgr_script_iseqs
|
17
|
+
attr_reader :dbgr_iseqs
|
18
|
+
|
19
|
+
include Trepanning::Method
|
20
|
+
include Trepan::Validate
|
21
|
+
## include Trepan::ThreadHelper
|
22
|
+
## include Trepan::Condition
|
23
|
+
|
24
|
+
def confirm(msg, default)
|
25
|
+
@dbgr.intf[-1].confirm(msg, default)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Like cmdfns.get_an_int(), but if there's a stack frame use that
|
29
|
+
# in evaluation.
|
30
|
+
def get_an_int(arg, opts={})
|
31
|
+
ret_value = get_int_noerr(arg)
|
32
|
+
if !ret_value
|
33
|
+
if opts[:msg_on_error]
|
34
|
+
errmsg(opts[:msg_on_error])
|
35
|
+
else
|
36
|
+
errmsg("Expecting an integer, got: #{arg}.")
|
37
|
+
end
|
38
|
+
return nil
|
39
|
+
end
|
40
|
+
if opts[:min_value] and ret_value < opts[:min_value]
|
41
|
+
errmsg("Expecting integer value to be at least %d; got %d." %
|
42
|
+
[opts[:min_value], ret_value])
|
43
|
+
return nil
|
44
|
+
elsif opts[:max_value] and ret_value > opts[:max_value]
|
45
|
+
errmsg("Expecting integer value to be at most %d; got %d." %
|
46
|
+
[opts[:max_value], ret_value])
|
47
|
+
return nil
|
48
|
+
end
|
49
|
+
return ret_value
|
50
|
+
end
|
51
|
+
|
52
|
+
unless defined?(DEFAULT_GET_INT_OPTS)
|
53
|
+
DEFAULT_GET_INT_OPTS = {
|
54
|
+
:min_value => 0, :default => 1, :cmdname => nil, :max_value => nil}
|
55
|
+
end
|
56
|
+
|
57
|
+
# If argument parameter 'arg' is not given, then use what is in
|
58
|
+
# opts[:default]. If String 'arg' evaluates to an integer between
|
59
|
+
# least min_value and at_most, use that. Otherwise report an
|
60
|
+
# error. If there's a stack frame use that for bindings in
|
61
|
+
# evaluation.
|
62
|
+
def get_int(arg, opts={})
|
63
|
+
|
64
|
+
return default unless arg
|
65
|
+
opts = DEFAULT_GET_INT_OPTS.merge(opts)
|
66
|
+
val = arg ? get_int_noerr(arg) : opts[:default]
|
67
|
+
unless val
|
68
|
+
if opts[:cmdname]
|
69
|
+
errmsg(("Command '%s' expects an integer; " +
|
70
|
+
"got: %s.") % [opts[:cmdname], arg])
|
71
|
+
else
|
72
|
+
errmsg('Expecting a positive integer, got: %s' % arg)
|
73
|
+
end
|
74
|
+
return nil
|
75
|
+
end
|
76
|
+
|
77
|
+
if val < opts[:min_value]
|
78
|
+
if cmdname
|
79
|
+
errmsg(("Command '%s' expects an integer at least" +
|
80
|
+
' %d; got: %d.') %
|
81
|
+
[cmdname, opts[:min_value], opts[:default]])
|
82
|
+
else
|
83
|
+
errmsg(("Expecting a positive integer at least" +
|
84
|
+
' %d; got: %d') %
|
85
|
+
[opts[:min_value], opts[:default]])
|
86
|
+
end
|
87
|
+
return nil
|
88
|
+
elsif opts[:max_value] and val > opts[:max_value]
|
89
|
+
if opts[:cmdname]
|
90
|
+
errmsg(("Command '%s' expects an integer at most" +
|
91
|
+
' %d; got: %d.') %
|
92
|
+
[opts[:cmdname], opts[:max_value], val])
|
93
|
+
else
|
94
|
+
errmsg(("Expecting an integer at most %d; got: %d") %
|
95
|
+
[opts[:max_value], val])
|
96
|
+
end
|
97
|
+
return nil
|
98
|
+
end
|
99
|
+
return val
|
100
|
+
end
|
101
|
+
|
102
|
+
def get_int_list(args, opts={})
|
103
|
+
args.map{|arg| get_an_int(arg, opts)}.compact
|
104
|
+
end
|
105
|
+
|
106
|
+
# Eval arg and it is an integer return the value. Otherwise
|
107
|
+
# return nil
|
108
|
+
def get_int_noerr(arg)
|
109
|
+
b = @frame ? @frame.binding : nil
|
110
|
+
val = Integer(eval(arg, b))
|
111
|
+
rescue SyntaxError
|
112
|
+
nil
|
113
|
+
rescue
|
114
|
+
nil
|
115
|
+
end
|
116
|
+
|
117
|
+
def get_thread_from_string(id_or_num_str)
|
118
|
+
if id_or_num_str == '.'
|
119
|
+
Thread.current
|
120
|
+
elsif id_or_num_str.downcase == 'm'
|
121
|
+
Thread.main
|
122
|
+
else
|
123
|
+
num = get_int_noerr(id_or_num_str)
|
124
|
+
if num
|
125
|
+
get_thread(num)
|
126
|
+
else
|
127
|
+
nil
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Parse a breakpoint position. On success return
|
133
|
+
# - a string "description"
|
134
|
+
# - the method the position is in - a CompiledMethod or a String
|
135
|
+
# - the line - a Fixnum
|
136
|
+
# - whether the position is an instance or not
|
137
|
+
# On failure, an error message is shown and we return nil.
|
138
|
+
def breakpoint_position(args)
|
139
|
+
ip = nil
|
140
|
+
if args.size == 0
|
141
|
+
args = [frame.line.to_s]
|
142
|
+
end
|
143
|
+
if args[0] == 'main.__script__'
|
144
|
+
if args.size > 2
|
145
|
+
errmsg 'Expecting only a line number'
|
146
|
+
return nil
|
147
|
+
elsif args.size == 2
|
148
|
+
ip, line = line_or_ip(args[1])
|
149
|
+
unless line || ip
|
150
|
+
errmsg ("Expecting a line or an IP offset number")
|
151
|
+
return nil
|
152
|
+
end
|
153
|
+
else
|
154
|
+
ip, line = nil, nil
|
155
|
+
end
|
156
|
+
return [args.join(' '), '.', '__script__', line, ip]
|
157
|
+
elsif args.size == 1
|
158
|
+
meth = parse_method(args[0])
|
159
|
+
if meth
|
160
|
+
cm = meth.executable
|
161
|
+
return [args[0], nil, true, cm, cm.lines[1], cm.lines[0]]
|
162
|
+
else
|
163
|
+
m = /([A-Z]\w*(?:::[A-Z]\w*)*)([.#])(\w+[!?=]?)(?:[:]([oO])?(\d+))?/.match(args[0])
|
164
|
+
if m
|
165
|
+
if m[4]
|
166
|
+
return [m[0], m[1], m[2], m[3], nil, m[5] ? m[5].to_i : nil]
|
167
|
+
else
|
168
|
+
return [m[0], m[1], m[2], m[3], (m[4] ? m[4].to_i : nil), nil]
|
169
|
+
end
|
170
|
+
else
|
171
|
+
ip, line = line_or_ip(args[0])
|
172
|
+
unless line || ip
|
173
|
+
errmsg ("Expecting a line or an IP offset number")
|
174
|
+
return nil
|
175
|
+
end
|
176
|
+
if line
|
177
|
+
meth = find_method_with_line(frame.method, line)
|
178
|
+
unless meth
|
179
|
+
errmsg "Cannot find method location for line #{line}"
|
180
|
+
return nil
|
181
|
+
end
|
182
|
+
elsif valid_ip?(frame.method, ip)
|
183
|
+
return [args.join(' '), meth.class, '#', frame.method, nil, ip]
|
184
|
+
else
|
185
|
+
errmsg 'Cannot parse breakpoint location'
|
186
|
+
return nil
|
187
|
+
end
|
188
|
+
|
189
|
+
return ["#{meth.describe}", nil, '#', meth, line, nil]
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
errmsg 'Cannot parse breakpoint location'
|
194
|
+
return nil
|
195
|
+
end
|
196
|
+
|
197
|
+
# Return true if arg is 'on' or 1 and false arg is 'off' or 0.
|
198
|
+
# Any other value is raises TypeError.
|
199
|
+
def get_onoff(arg, default=nil, print_error=true)
|
200
|
+
unless arg
|
201
|
+
if !default
|
202
|
+
if print_error
|
203
|
+
errmsg("Expecting 'on', 1, 'off', or 0. Got nothing.")
|
204
|
+
end
|
205
|
+
raise TypeError
|
206
|
+
end
|
207
|
+
return default
|
208
|
+
end
|
209
|
+
darg = arg.downcase
|
210
|
+
return true if arg == '1' || darg == 'on'
|
211
|
+
return false if arg == '0' || darg =='off'
|
212
|
+
|
213
|
+
errmsg("Expecting 'on', 1, 'off', or 0. Got: %s." % arg.to_s) if
|
214
|
+
print_error
|
215
|
+
raise TypeError
|
216
|
+
end
|
217
|
+
|
218
|
+
def method?(method_string)
|
219
|
+
obj, type, meth =
|
220
|
+
if method_string =~ /(.+)(#|::|\.)(.+)/
|
221
|
+
[$1, $2, $3]
|
222
|
+
else
|
223
|
+
['self', '.', method_string]
|
224
|
+
end
|
225
|
+
ret = debug_eval_no_errmsg("#{obj}.method(#{meth.inspect})")
|
226
|
+
return true if ret
|
227
|
+
return debug_eval_no_errmsg("#{obj}.is_a?(Class)") &&
|
228
|
+
debug_eval_no_errmsg("#{obj}.method_defined?(#{meth.inspect})")
|
229
|
+
end
|
230
|
+
|
231
|
+
# parse_position(self, arg)->(fn, container, lineno)
|
232
|
+
#
|
233
|
+
# Parse arg as [filename:]lineno | function | module
|
234
|
+
# Make sure it works for C:\foo\bar.py:12
|
235
|
+
def parse_position(arg, old_mod=nil, allow_offset = false)
|
236
|
+
colon = arg.rindex(':')
|
237
|
+
if colon
|
238
|
+
# First handle part before the colon
|
239
|
+
arg1 = arg[0...colon].rstrip
|
240
|
+
lineno_str = arg[colon+1..-1].lstrip
|
241
|
+
mf, container, lineno = parse_position_one_arg(arg1, old_mod, false, allow_offset)
|
242
|
+
return nil, nil, nil unless container
|
243
|
+
filename = canonic_file(arg1)
|
244
|
+
# Next handle part after the colon
|
245
|
+
val = get_an_int(lineno_str)
|
246
|
+
lineno = val if val
|
247
|
+
else
|
248
|
+
mf, container, lineno = parse_position_one_arg(arg, old_mod, true, allow_offset)
|
249
|
+
end
|
250
|
+
|
251
|
+
return mf, container, lineno
|
252
|
+
end
|
253
|
+
|
254
|
+
# parse_position_one_arg(self,arg)->(module/function, container, lineno)
|
255
|
+
#
|
256
|
+
# See if arg is a line number, function name, or module name.
|
257
|
+
# Return what we've found. nil can be returned as a value in
|
258
|
+
# the triple.
|
259
|
+
def parse_position_one_arg(arg, old_mod=nil, show_errmsg=true, allow_offset=false)
|
260
|
+
name, filename = nil, nil, nil
|
261
|
+
begin
|
262
|
+
# First see if argument is an integer
|
263
|
+
lineno = Integer(arg)
|
264
|
+
rescue
|
265
|
+
else
|
266
|
+
filename = @frame.file
|
267
|
+
return nil, canonic_file(filename), lineno
|
268
|
+
end
|
269
|
+
|
270
|
+
# Next see if argument is a file name
|
271
|
+
if LineCache::cached?(arg)
|
272
|
+
return nil, canonic_file(arg), 1
|
273
|
+
elsif File.readable?(arg)
|
274
|
+
return nil, canonic_file(arg), 1
|
275
|
+
end
|
276
|
+
|
277
|
+
# How about a method name with an instruction sequence?
|
278
|
+
meth = parse_method(arg)
|
279
|
+
if meth
|
280
|
+
cm = meth.executable
|
281
|
+
return arg, canonic_file(cm.active_path), cm.lines[1]
|
282
|
+
end
|
283
|
+
|
284
|
+
if show_errmsg
|
285
|
+
unless (allow_offset && arg.size > 0 && arg[0].downcase == 'o')
|
286
|
+
errmsg("#{arg} is not a line number, filename or method " +
|
287
|
+
"we can get location information about")
|
288
|
+
end
|
289
|
+
end
|
290
|
+
return nil, nil, nil
|
291
|
+
end
|
292
|
+
|
293
|
+
def parse_method(meth_str)
|
294
|
+
# For meth_str = "foo", try via method("foo".to_sym)
|
295
|
+
str = "method(#{meth_str.inspect}.to_sym)"
|
296
|
+
meth = debug_eval_no_errmsg(str)
|
297
|
+
return meth if meth
|
298
|
+
last_dot = meth_str.rindex('.')
|
299
|
+
if last_dot
|
300
|
+
# For meth_str = "a.b.foo",
|
301
|
+
# try via a.b.method("foo".to_sym)
|
302
|
+
try_eval = "#{meth_str[0..last_dot]}method" +
|
303
|
+
"(#{meth_str[last_dot+1..-1].inspect}.to_sym)"
|
304
|
+
meth = debug_eval_no_errmsg(try_eval)
|
305
|
+
end
|
306
|
+
return meth
|
307
|
+
end
|
308
|
+
|
309
|
+
def validate_initialize
|
310
|
+
## top_srcdir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
311
|
+
## @dbgr_script_iseqs, @dbgr_iseqs = filter_scripts(top_srcdir)
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
if __FILE__ == $0
|
317
|
+
# Demo it.
|
318
|
+
require_relative './mock'
|
319
|
+
dbgr, cmd = MockDebugger::setup('exit', false)
|
320
|
+
proc = cmd.proc
|
321
|
+
onoff = %w(1 0 on off)
|
322
|
+
onoff.each { |val| puts "onoff(#{val}) = #{proc.get_onoff(val)}" }
|
323
|
+
%w(1 1E bad 1+1 -5).each do |val|
|
324
|
+
puts "get_int_noerr(#{val}) = #{proc.get_int_noerr(val).inspect}"
|
325
|
+
end
|
326
|
+
def foo; 5 end
|
327
|
+
def proc.errmsg(msg)
|
328
|
+
puts msg
|
329
|
+
end
|
330
|
+
puts proc.parse_position_one_arg('tmpdir.rb').inspect
|
331
|
+
|
332
|
+
puts '=' * 40
|
333
|
+
['Array#map', 'Trepan::CmdProcessor.new',
|
334
|
+
'foo', 'proc.errmsg'].each do |str|
|
335
|
+
puts "#{str} should be true: #{proc.method?(str).inspect}"
|
336
|
+
end
|
337
|
+
puts '=' * 40
|
338
|
+
|
339
|
+
# FIXME:
|
340
|
+
# Array#foo should be false: true
|
341
|
+
# Trepan::CmdProcessor.allocate should be false: true
|
342
|
+
|
343
|
+
['food', '.errmsg'].each do |str|
|
344
|
+
puts "#{str} should be false: #{proc.method?(str).inspect}"
|
345
|
+
end
|
346
|
+
puts '-' * 20
|
347
|
+
# require_relative '../lib/trepanning'
|
348
|
+
# Trepan.start
|
349
|
+
p proc.breakpoint_position(%w(O0))
|
350
|
+
p proc.breakpoint_position(%w(1))
|
351
|
+
p proc.breakpoint_position(%w(__LINE__))
|
352
|
+
# p proc.breakpoint_position(%w(2 if a > b))
|
353
|
+
p proc.get_int_list(%w(1+0 3-1 3))
|
354
|
+
p proc.get_int_list(%w(a 2 3))
|
355
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
gcd.rb:4
|
2
|
+
def gcd(a, b)
|
3
|
+
# # ********************************************************
|
4
|
+
# # This tests the enable command.
|
5
|
+
# # ********************************************************
|
6
|
+
# set debuggertesting on
|
7
|
+
Currently testing the debugger is on.
|
8
|
+
# set callstyle last
|
9
|
+
Frame call-display style is last.
|
10
|
+
# set autoeval off
|
11
|
+
autoeval is off.
|
12
|
+
# break Object.gcd
|
13
|
+
Breakpoint 1 at Object::gcd
|
14
|
+
# # Should have a breakpoint 1
|
15
|
+
# enable br 1
|
16
|
+
# # Get help on enable
|
17
|
+
# help enable
|
18
|
+
Enable some things.
|
19
|
+
This is used to cancel the effect of the "disable" command.
|
20
|
+
--
|
21
|
+
List of enable subcommands:
|
22
|
+
--
|
23
|
+
enable breakpoints -- Enable specified breakpoints
|
24
|
+
enable display -- Enable some expressions to be displayed when program stops
|
25
|
+
# # Get help on just enable break
|
26
|
+
# help enable break
|
27
|
+
Enable specified breakpoints.
|
28
|
+
Give breakpoint numbers (separated by spaces) as arguments.
|
29
|
+
This is used to cancel the effect of the "disable" command.
|
30
|
+
# # Plain enable should work
|
31
|
+
# enable
|
32
|
+
*** "enable" must be followed "display", "breakpoints" or breakpoint numbers.
|
33
|
+
# # An invalid enable command
|
34
|
+
# enable foo
|
35
|
+
Enable breakpoints argument 'foo' needs to be a number.
|
36
|
+
# quit
|
@@ -0,0 +1 @@
|
|
1
|
+
Ha!
|
data/test/data/quit.cmd
ADDED
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
puts "Ha!"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
# GCD. We assume positive numbers
|
3
|
+
def gcd(a, b)
|
4
|
+
# Make: a <= b
|
5
|
+
if a > b
|
6
|
+
a, b = [b, a]
|
7
|
+
end
|
8
|
+
|
9
|
+
return nil if a <= 0
|
10
|
+
addline
|
11
|
+
|
12
|
+
if a == 1 or b-a == 0
|
13
|
+
return a
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
a, b = ARGV[0..1].map {|arg| arg.to_i}
|
18
|
+
puts "The GCD of %d and %d is %d" % [a, b, gcd(a, b)]
|
data/test/example/gcd.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# GCD. We assume positive numbers
|
4
|
+
def gcd(a, b)
|
5
|
+
# Make: a <= b
|
6
|
+
if a > b
|
7
|
+
a, b = [b, a]
|
8
|
+
end
|
9
|
+
|
10
|
+
return nil if a <= 0
|
11
|
+
|
12
|
+
if a == 1 or b-a == 0
|
13
|
+
return a
|
14
|
+
end
|
15
|
+
return gcd(b-a, a)
|
16
|
+
end
|
17
|
+
|
18
|
+
a, b = ARGV[0..1].map {|arg| arg.to_i}
|
19
|
+
puts "The GCD of %d and %d is %d" % [a, b, gcd(a, b)]
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'thread_frame'
|
3
|
+
tf = RubyVM::ThreadFrame.current
|
4
|
+
iseq = tf.iseq
|
5
|
+
p iseq.child_iseqs
|
6
|
+
puts iseq.disassemble
|
7
|
+
|
8
|
+
# GCD. We assume positive numbers
|
9
|
+
def gcd(a, b)
|
10
|
+
# Make: a <= b
|
11
|
+
if a > b
|
12
|
+
a, b = [b, a]
|
13
|
+
end
|
14
|
+
|
15
|
+
return nil if a <= 0
|
16
|
+
|
17
|
+
if a == 1 or b-a == 0
|
18
|
+
return a
|
19
|
+
end
|
20
|
+
return gcd(b-a, a)
|
21
|
+
end
|
22
|
+
|
23
|
+
a, b = ARGV[0..1].map {|arg| arg.to_i}
|
24
|
+
puts "The GCD of %d and %d is %d" % [a, b, gcd(a, b)]
|
@@ -0,0 +1 @@
|
|
1
|
+
# Nothing here. Move along.
|
@@ -0,0 +1,112 @@
|
|
1
|
+
## require 'thread_frame'
|
2
|
+
## require 'trace'
|
3
|
+
require 'rubygems'; require 'require_relative'
|
4
|
+
require_relative '../../lib/trepanning'
|
5
|
+
require_relative '../../io/string_array'
|
6
|
+
|
7
|
+
module FnTestHelper
|
8
|
+
## include Trace
|
9
|
+
|
10
|
+
## # Synchronous events without C frames or instructions
|
11
|
+
# Common setup to create a debugger with String Array I/O attached
|
12
|
+
def strarray_setup(debugger_cmds, insn_stepping=false)
|
13
|
+
stringin = Trepan::StringArrayInput.open(debugger_cmds)
|
14
|
+
stringout = Trepan::StringArrayOutput.open
|
15
|
+
d_opts = {:input => stringin, :output => stringout,
|
16
|
+
:nx => true}
|
17
|
+
d = Trepan.new(d_opts)
|
18
|
+
|
19
|
+
d.settings[:basename] = true
|
20
|
+
d.settings[:different] = false
|
21
|
+
d.settings[:autoeval] = false
|
22
|
+
return d
|
23
|
+
end
|
24
|
+
|
25
|
+
unless defined?(TREPAN_PROMPT)
|
26
|
+
TREPAN_PROMPT = /^\(trepanx\): /
|
27
|
+
TREPAN_LOC = /.. \(.+:\d+( @\d+)?\)/
|
28
|
+
end
|
29
|
+
|
30
|
+
# Return the caller's line number
|
31
|
+
def get_lineno
|
32
|
+
Rubinius::VM.backtrace(0)[1].line
|
33
|
+
end
|
34
|
+
|
35
|
+
def compare_output(right, d, debugger_cmds)
|
36
|
+
# require_relative '../../lib/trepanning'
|
37
|
+
# Trepan.debug(:set_restart => true)
|
38
|
+
got = filter_line_cmd(d.intf[-1].output.output)
|
39
|
+
if got != right
|
40
|
+
got.each_with_index do |got_line, i|
|
41
|
+
if i < right.size and got_line != right[i]
|
42
|
+
# dbgr.debugger
|
43
|
+
puts "! #{got_line}"
|
44
|
+
else
|
45
|
+
puts " #{got_line}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
puts '-' * 10
|
49
|
+
right.each_with_index do |right_line, i|
|
50
|
+
if i < got.size and got[i] != right_line
|
51
|
+
# dbgr.debugger
|
52
|
+
puts "! #{right_line}"
|
53
|
+
else
|
54
|
+
puts " #{right_line}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
assert_equal(right, got, caller[0])
|
59
|
+
end
|
60
|
+
|
61
|
+
# Return output with source lines prompt and command removed
|
62
|
+
def filter_line_cmd(a, show_prompt=false)
|
63
|
+
# Remove debugger prompt
|
64
|
+
a = a.map do |s|
|
65
|
+
s =~ TREPAN_PROMPT ? nil : s
|
66
|
+
end.compact unless show_prompt
|
67
|
+
|
68
|
+
# Remove debugger location lines.
|
69
|
+
# For example:
|
70
|
+
# -- (/src/external-vcs/trepan/tmp/gcd.rb:4 @21)
|
71
|
+
# becomes:
|
72
|
+
# --
|
73
|
+
a2 = a.map do |s|
|
74
|
+
s =~ TREPAN_LOC ? s.gsub(/\(.+:\d+( @\d+)?\)\n/, '').chomp : s.chomp
|
75
|
+
end
|
76
|
+
|
77
|
+
# Canonicalize breakpoint messages.
|
78
|
+
# For example:
|
79
|
+
# Set breakpoint 1: test/functional/test-tbreak.rb:10 (@0)
|
80
|
+
# becomes :
|
81
|
+
# Set breakpoint 1: foo.rb:55 (@3)
|
82
|
+
a3 = a2.map do |s|
|
83
|
+
s.gsub(/^Set (temporary )?breakpoint (\d+): .+:(\d+) \(@\d+\)/,
|
84
|
+
'Set \1breakpoint \2: foo.rb:55 (@3)')
|
85
|
+
end
|
86
|
+
return a3
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
# Demo it
|
92
|
+
if __FILE__ == $0
|
93
|
+
include FnTestHelper
|
94
|
+
strarray_setup(%w(eh bee see))
|
95
|
+
puts get_lineno()
|
96
|
+
p '-- (/src/external-vcs/trepan/tmp/gcd.rb:4)' =~ TREPAN_LOC
|
97
|
+
p '(trepan): exit' =~ TREPAN_PROMPT
|
98
|
+
output='
|
99
|
+
-- (/src/external-vcs/trepan/tmp/gcd.rb:4)
|
100
|
+
(trepan): s
|
101
|
+
-- (/src/external-vcs/trepan/tmp/gcd.rb:18)
|
102
|
+
(trepan): s
|
103
|
+
-- (/src/external-vcs/trepan/tmp/gcd.rb:19)
|
104
|
+
(trepan): s
|
105
|
+
.. (/src/external-vcs/trepan/tmp/gcd.rb:0)
|
106
|
+
(trepan): s
|
107
|
+
-> (/src/external-vcs/trepan/tmp/gcd.rb:4)
|
108
|
+
'.split(/\n/)
|
109
|
+
puts filter_line_cmd(output)
|
110
|
+
puts '-' * 10
|
111
|
+
puts filter_line_cmd(output, true)
|
112
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'test/unit'
|
3
|
+
require 'rubygems'; require 'require_relative'
|
4
|
+
require_relative 'fn_helper'
|
5
|
+
|
6
|
+
def five
|
7
|
+
5
|
8
|
+
end
|
9
|
+
|
10
|
+
class TestNameBreak < Test::Unit::TestCase
|
11
|
+
|
12
|
+
include FnTestHelper
|
13
|
+
|
14
|
+
def self.six=(val)
|
15
|
+
@six = val
|
16
|
+
end
|
17
|
+
|
18
|
+
def five?(num) 5 == num; end
|
19
|
+
|
20
|
+
def test_basic
|
21
|
+
# Check that we can set breakpoints in parent, sibling and children
|
22
|
+
# of sibling returns. We have one more 'continue' than we need
|
23
|
+
# just in case something goes wrong.
|
24
|
+
cmds = ['break Object#five', 'break TestNameBreak#five?',
|
25
|
+
'break TestNameBreak.six=',
|
26
|
+
'continue', 'continue', 'continue', 'continue']
|
27
|
+
|
28
|
+
d = strarray_setup(cmds)
|
29
|
+
##############################
|
30
|
+
d.start
|
31
|
+
five
|
32
|
+
five?(5)
|
33
|
+
TestNameBreak::six=6
|
34
|
+
##############################
|
35
|
+
d.stop # ({:remove => true})
|
36
|
+
out = ["-- ",
|
37
|
+
"five ",
|
38
|
+
"Set breakpoint 1: foo.rb:55 (@3)",
|
39
|
+
"Set breakpoint 2: foo.rb:55 (@3)",
|
40
|
+
"Set breakpoint 3: foo.rb:55 (@3)",
|
41
|
+
"xx ",
|
42
|
+
"5",
|
43
|
+
"xx ",
|
44
|
+
"def five?(num) 5 == num; end",
|
45
|
+
"xx ",
|
46
|
+
"@six = val"]
|
47
|
+
compare_output(out, d, cmds)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
|