rb8-trepanning 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +10 -0
- data/ChangeLog +276 -0
- data/Makefile +13 -0
- data/Rakefile +1 -2
- data/app/display.rb +41 -1
- data/app/irb.rb +55 -49
- data/app/options.rb +3 -2
- data/app/run.rb +25 -7
- data/app/util.rb +19 -1
- data/bin/trepan8 +0 -2
- data/data/perldb.bindings +17 -0
- data/interface/script.rb +1 -1
- data/interface/server.rb +1 -1
- data/interface/user.rb +3 -1
- data/{interface/base_intf.rb → interface.rb} +1 -1
- data/io/input.rb +1 -1
- data/io/null_output.rb +1 -1
- data/io/string_array.rb +2 -2
- data/io/tcpclient.rb +1 -1
- data/io/tcpserver.rb +1 -1
- data/{io/base_io.rb → io.rb} +0 -0
- data/lib/debugger.rb +0 -1
- data/lib/trepanning.rb +3 -1
- data/processor/command/alias.rb +13 -2
- data/processor/command/backtrace.rb +2 -1
- data/processor/command/base/subcmd.rb +1 -5
- data/processor/command/base/submgr.rb +1 -1
- data/processor/command/base/subsubcmd.rb +1 -1
- data/processor/command/base/subsubmgr.rb +4 -4
- data/processor/command/break.rb +19 -11
- data/processor/command/catch.rb +1 -1
- data/processor/command/complete.rb +1 -1
- data/processor/command/continue.rb +7 -1
- data/processor/command/directory.rb +2 -2
- data/processor/command/disable.rb +13 -14
- data/processor/command/display.rb +3 -1
- data/processor/command/down.rb +8 -8
- data/processor/command/edit.rb +1 -1
- data/processor/command/enable.rb +21 -22
- data/processor/command/eval.rb +1 -2
- data/processor/command/exit.rb +25 -8
- data/processor/command/finish.rb +7 -2
- data/processor/command/frame.rb +1 -1
- data/processor/command/help.rb +3 -4
- data/processor/command/info.rb +2 -0
- data/processor/command/info_subcmd/files.rb +2 -2
- data/processor/command/info_subcmd/locals.rb +6 -53
- data/processor/command/info_subcmd/source.rb +10 -4
- data/processor/command/info_subcmd/variables.rb +35 -0
- data/processor/command/info_subcmd/variables_subcmd/.gitignore +1 -0
- data/processor/command/info_subcmd/variables_subcmd/class.rb +42 -0
- data/processor/command/info_subcmd/variables_subcmd/constant.rb +42 -0
- data/processor/command/info_subcmd/{globals.rb → variables_subcmd/globals.rb} +22 -17
- data/processor/command/info_subcmd/variables_subcmd/instance.rb +42 -0
- data/processor/command/info_subcmd/variables_subcmd/locals.rb +80 -0
- data/processor/command/kill.rb +8 -7
- data/processor/command/list.rb +2 -2
- data/processor/command/macro.rb +27 -9
- data/processor/command/next.rb +1 -1
- data/processor/command/parsetree.rb +1 -1
- data/processor/command/pp.rb +1 -1
- data/processor/command/pr.rb +1 -1
- data/processor/command/ps.rb +1 -1
- data/processor/command/restart.rb +1 -1
- data/processor/command/save.rb +1 -1
- data/processor/command/set_subcmd/auto.rb +7 -1
- data/processor/command/set_subcmd/different.rb +1 -1
- data/processor/command/set_subcmd/trace.rb +5 -4
- data/processor/command/set_subcmd/trace_subcmd/print.rb +4 -3
- data/processor/command/shell.rb +5 -4
- data/processor/command/show_subcmd/{alias.rb → aliases.rb} +2 -2
- data/processor/command/source.rb +1 -1
- data/processor/command/step.rb +2 -5
- data/processor/command/tbreak.rb +1 -1
- data/processor/command/unalias.rb +13 -8
- data/processor/command/undisplay.rb +13 -9
- data/processor/command/up.rb +12 -14
- data/processor/command.rb +138 -230
- data/processor/display.rb +46 -10
- data/processor/help.rb +5 -3
- data/processor/hook.rb +2 -2
- data/processor/location.rb +25 -0
- data/processor/mock.rb +3 -2
- data/processor/msg.rb +55 -42
- data/processor/old-command.rb +270 -0
- data/processor/{processor.rb → old-processor.rb} +7 -8
- data/processor/running.rb +7 -12
- data/processor/subcmd.rb +15 -41
- data/processor/validate.rb +240 -238
- data/{processor/main.rb → processor.rb} +20 -42
- data/test/data/trace.cmd +6 -0
- data/test/data/trace.right +46 -0
- data/test/integration/helper.rb +2 -0
- data/test/integration/test-trace.rb +29 -0
- data/test/unit/cmd-helper.rb +2 -3
- data/test/unit/test-app-options.rb +13 -11
- data/test/unit/test-app-run.rb +7 -1
- data/test/unit/test-base-cmd.rb +1 -1
- data/test/unit/test-cmd-kill.rb +11 -4
- data/test/unit/test-io-tcpserver.rb +9 -4
- data/test/unit/test-proc-eval.rb +1 -2
- data/test/unit/test-proc-location.rb +26 -32
- data/test/unit/test-subcmd-help.rb +1 -1
- data/trepan8.gemspec +9 -1
- metadata +60 -17
- data/processor/command/base/cmd.rb +0 -177
data/processor/validate.rb
CHANGED
@@ -21,280 +21,282 @@ require_relative '../app/cmd_parse'
|
|
21
21
|
require_relative 'virtual'
|
22
22
|
require_relative 'msg' # for errmsg, msg
|
23
23
|
|
24
|
-
|
24
|
+
module Trepan
|
25
|
+
class CmdProcessor < VirtualCmdProcessor
|
25
26
|
|
26
|
-
|
27
|
-
|
27
|
+
attr_reader :file_exists_proc # Like File.exists? but checks using
|
28
|
+
# cached files
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
## include Trepanning::Method
|
31
|
+
## include Trepanning::FileName
|
32
|
+
## include Trepan::Validate
|
33
|
+
## include Trepan::ThreadHelper
|
34
|
+
## include Trepan::Condition
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
def confirm(msg, default)
|
37
|
+
@settings[:confirm] ? @intf.confirm(msg, default) : true
|
38
|
+
end
|
39
|
+
|
39
40
|
# Like cmdfns.get_an_int(), but if there's a stack frame use that
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
41
|
+
# in evaluation.
|
42
|
+
def get_an_int(arg, opts={})
|
43
|
+
ret_value = get_int_noerr(arg)
|
44
|
+
if !ret_value
|
45
|
+
if opts[:msg_on_error]
|
46
|
+
errmsg(opts[:msg_on_error])
|
47
|
+
else
|
48
|
+
errmsg("Expecting an integer, got: #{arg}.")
|
49
|
+
end
|
50
|
+
return nil
|
48
51
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
return
|
52
|
+
if opts[:min_value] and ret_value < opts[:min_value]
|
53
|
+
errmsg("Expecting integer value to be at least %d; got %d." %
|
54
|
+
[opts[:min_value], ret_value])
|
55
|
+
return nil
|
56
|
+
elsif opts[:max_value] and ret_value > opts[:max_value]
|
57
|
+
errmsg("Expecting integer value to be at most %d; got %d." %
|
58
|
+
[opts[:max_value], ret_value])
|
59
|
+
return nil
|
60
|
+
end
|
61
|
+
return ret_value
|
59
62
|
end
|
60
|
-
return ret_value
|
61
|
-
end
|
62
|
-
|
63
|
-
unless defined?(DEFAULT_GET_INT_OPTS)
|
64
|
-
DEFAULT_GET_INT_OPTS = {
|
65
|
-
:min_value => 0, :default => 1, :cmdname => nil, :max_value => nil}
|
66
|
-
end
|
67
|
-
|
68
|
-
# If argument parameter 'arg' is not given, then use what is in
|
69
|
-
# opts[:default]. If String 'arg' evaluates to an integer between
|
70
|
-
# least min_value and at_most, use that. Otherwise report an
|
71
|
-
# error. If there's a stack frame use that for bindings in
|
72
|
-
# evaluation.
|
73
|
-
def get_int(arg, opts={})
|
74
63
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
unless val
|
79
|
-
if opts[:cmdname]
|
80
|
-
errmsg(("Command '%s' expects an integer; " +
|
81
|
-
"got: %s.") % [opts[:cmdname], arg])
|
82
|
-
else
|
83
|
-
errmsg('Expecting a positive integer, got: %s' % arg)
|
84
|
-
end
|
85
|
-
return nil
|
64
|
+
unless defined?(DEFAULT_GET_INT_OPTS)
|
65
|
+
DEFAULT_GET_INT_OPTS = {
|
66
|
+
:min_value => 0, :default => 1, :cmdname => nil, :max_value => nil}
|
86
67
|
end
|
87
68
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
69
|
+
# If argument parameter 'arg' is not given, then use what is in
|
70
|
+
# opts[:default]. If String 'arg' evaluates to an integer between
|
71
|
+
# least min_value and at_most, use that. Otherwise report an
|
72
|
+
# error. If there's a stack frame use that for bindings in
|
73
|
+
# evaluation.
|
74
|
+
def get_int(arg, opts={})
|
75
|
+
|
76
|
+
return default unless arg
|
77
|
+
opts = DEFAULT_GET_INT_OPTS.merge(opts)
|
78
|
+
val = arg ? get_int_noerr(arg) : opts[:default]
|
79
|
+
unless val
|
80
|
+
if opts[:cmdname]
|
81
|
+
errmsg(("Command '%s' expects an integer; " +
|
82
|
+
"got: %s.") % [opts[:cmdname], arg])
|
83
|
+
else
|
84
|
+
errmsg('Expecting a positive integer, got: %s' % arg)
|
85
|
+
end
|
86
|
+
return nil
|
97
87
|
end
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
88
|
+
|
89
|
+
if val < opts[:min_value]
|
90
|
+
if opts[:cmdname]
|
91
|
+
errmsg(("Command '%s' expects an integer at least" +
|
92
|
+
' %d; got: %d.') %
|
93
|
+
[opts[:cmdname], opts[:min_value], opts[:default]])
|
94
|
+
else
|
95
|
+
errmsg(("Expecting a positive integer at least" +
|
96
|
+
' %d; got: %d') %
|
97
|
+
[opts[:min_value], opts[:default]])
|
98
|
+
end
|
99
|
+
return nil
|
100
|
+
elsif opts[:max_value] and val > opts[:max_value]
|
101
|
+
if opts[:cmdname]
|
102
|
+
errmsg(("Command '%s' expects an integer at most" +
|
103
|
+
' %d; got: %d.') %
|
104
|
+
[opts[:cmdname], opts[:max_value], val])
|
105
|
+
else
|
106
|
+
errmsg(("Expecting an integer at most %d; got: %d") %
|
107
|
+
[opts[:max_value], val])
|
108
|
+
end
|
109
|
+
return nil
|
107
110
|
end
|
108
|
-
return
|
111
|
+
return val
|
109
112
|
end
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
def get_int_list(args, opts={})
|
114
|
-
args.map{|arg| get_an_int(arg, opts)}.compact
|
115
|
-
end
|
116
|
-
|
117
|
-
# Eval arg and it is an integer return the value. Otherwise
|
118
|
-
# return nil
|
119
|
-
def get_int_noerr(arg)
|
120
|
-
b = @frame ? @frame.binding : nil
|
121
|
-
val = Integer(eval(arg, b))
|
122
|
-
rescue SyntaxError
|
123
|
-
nil
|
124
|
-
rescue
|
125
|
-
nil
|
126
|
-
end
|
127
|
-
|
128
|
-
def get_thread_from_string(id_or_num_str)
|
129
|
-
if id_or_num_str == '.'
|
130
|
-
Thread.current
|
131
|
-
elsif id_or_num_str.downcase == 'm'
|
132
|
-
Thread.main
|
133
|
-
else
|
134
|
-
num = get_int_noerr(id_or_num_str)
|
135
|
-
if num
|
136
|
-
get_thread(num)
|
137
|
-
else
|
138
|
-
nil
|
139
|
-
end
|
113
|
+
|
114
|
+
def get_int_list(args, opts={})
|
115
|
+
args.map{|arg| get_an_int(arg, opts)}.compact
|
140
116
|
end
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
parse_breakpoint(position_str)
|
152
|
-
else
|
153
|
-
parse_breakpoint_no_condition(position_str)
|
154
|
-
end
|
155
|
-
return [nil] * 5 unless break_cmd_parse
|
156
|
-
tail = [break_cmd_parse.condition, break_cmd_parse.negate]
|
157
|
-
cm, file, line, position_type =
|
158
|
-
parse_position(break_cmd_parse.position)
|
159
|
-
if cm or file or line
|
160
|
-
return [cm, file, line, position_type] + tail
|
117
|
+
|
118
|
+
# Eval arg and it is an integer return the value. Otherwise
|
119
|
+
# return nil
|
120
|
+
def get_int_noerr(arg)
|
121
|
+
b = @frame ? @frame.binding : nil
|
122
|
+
val = Integer(eval(arg, b))
|
123
|
+
rescue SyntaxError
|
124
|
+
nil
|
125
|
+
rescue
|
126
|
+
nil
|
161
127
|
end
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
128
|
+
|
129
|
+
def get_thread_from_string(id_or_num_str)
|
130
|
+
if id_or_num_str == '.'
|
131
|
+
Thread.current
|
132
|
+
elsif id_or_num_str.downcase == 'm'
|
133
|
+
Thread.main
|
134
|
+
else
|
135
|
+
num = get_int_noerr(id_or_num_str)
|
136
|
+
if num
|
137
|
+
get_thread(num)
|
138
|
+
else
|
139
|
+
nil
|
173
140
|
end
|
174
|
-
raise TypeError
|
175
141
|
end
|
176
|
-
return default
|
177
142
|
end
|
178
|
-
darg = arg.downcase
|
179
|
-
return true if arg == '1' || darg == 'on'
|
180
|
-
return false if arg == '0' || darg =='off'
|
181
143
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
meth_for_parse_struct(meth, start_binding)
|
201
|
-
rescue NameError
|
202
|
-
errmsg("Can't evaluate #{meth.name} to get a method")
|
203
|
-
return nil
|
144
|
+
# Parse a breakpoint position. On success return:
|
145
|
+
# - the Method the position is in
|
146
|
+
# - the file name - a Fixnum
|
147
|
+
# - the line number - a Fixnum
|
148
|
+
# - the condition (by default 'true') to use for this breakpoint
|
149
|
+
# - true condition should be negated. Used in *condition* if/unless
|
150
|
+
def breakpoint_position(position_str, allow_condition)
|
151
|
+
break_cmd_parse = if allow_condition
|
152
|
+
parse_breakpoint(position_str)
|
153
|
+
else
|
154
|
+
parse_breakpoint_no_condition(position_str)
|
155
|
+
end
|
156
|
+
return [nil] * 5 unless break_cmd_parse
|
157
|
+
tail = [break_cmd_parse.condition, break_cmd_parse.negate]
|
158
|
+
cm, file, line, position_type =
|
159
|
+
parse_position(break_cmd_parse.position)
|
160
|
+
if cm or file or line
|
161
|
+
return [cm, file, line, position_type] + tail
|
204
162
|
end
|
163
|
+
errmsg("Unable to get breakpoint position for #{position_str}")
|
164
|
+
return [nil] * 5
|
205
165
|
end
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
# Make sure it works for C:\foo\bar.py:12
|
219
|
-
def parse_position(info)
|
220
|
-
info = parse_location(info) if info.kind_of?(String)
|
221
|
-
case info.container_type
|
222
|
-
when :fn
|
223
|
-
unless info.container
|
224
|
-
errmsg "Bad function parse #{info.container.inspect}"
|
225
|
-
return
|
166
|
+
|
167
|
+
# Return true if arg is 'on' or 1 and false arg is 'off' or 0.
|
168
|
+
# Any other value is raises TypeError.
|
169
|
+
def get_onoff(arg, default=nil, print_error=true)
|
170
|
+
unless arg
|
171
|
+
if !default
|
172
|
+
if print_error
|
173
|
+
errmsg("Expecting 'on', 1, 'off', or 0. Got nothing.")
|
174
|
+
end
|
175
|
+
raise TypeError
|
176
|
+
end
|
177
|
+
return default
|
226
178
|
end
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
179
|
+
darg = arg.downcase
|
180
|
+
return true if arg == '1' || darg == 'on'
|
181
|
+
return false if arg == '0' || darg =='off'
|
182
|
+
|
183
|
+
errmsg("Expecting 'on', 1, 'off', or 0. Got: %s." % arg.to_s) if
|
184
|
+
print_error
|
185
|
+
raise TypeError
|
186
|
+
end
|
187
|
+
|
188
|
+
include Trepan::CmdParser
|
189
|
+
|
190
|
+
def get_method(meth)
|
191
|
+
start_binding =
|
192
|
+
begin
|
193
|
+
@frame.binding
|
194
|
+
rescue
|
195
|
+
binding
|
196
|
+
end
|
197
|
+
if meth.kind_of?(String)
|
198
|
+
meth_for_string(meth, start_binding)
|
231
199
|
else
|
232
|
-
|
200
|
+
begin
|
201
|
+
meth_for_parse_struct(meth, start_binding)
|
202
|
+
rescue NameError
|
203
|
+
errmsg("Can't evaluate #{meth.name} to get a method")
|
204
|
+
return nil
|
205
|
+
end
|
233
206
|
end
|
234
|
-
|
235
|
-
|
207
|
+
end
|
208
|
+
|
209
|
+
# FIXME: this is a ? method but we return
|
210
|
+
# the method value.
|
211
|
+
def method?(meth)
|
212
|
+
get_method(meth)
|
213
|
+
end
|
214
|
+
|
215
|
+
# parse_position(self)->(meth, filename, offset, offset_type)
|
216
|
+
# See app/cmd_parser.kpeg for the syntax of a position which
|
217
|
+
# should include things like:
|
218
|
+
# Parse arg as [filename:]lineno | function | module
|
219
|
+
# Make sure it works for C:\foo\bar.py:12
|
220
|
+
def parse_position(info)
|
221
|
+
info = parse_location(info) if info.kind_of?(String)
|
222
|
+
case info.container_type
|
223
|
+
when :fn
|
224
|
+
unless info.container
|
225
|
+
errmsg "Bad function parse #{info.container.inspect}"
|
226
|
+
return
|
227
|
+
end
|
228
|
+
if cm = method?(info.container)
|
229
|
+
## Add bogus - canonic_file: active-path
|
230
|
+
return [cm, 'bogus', info.position,
|
231
|
+
info.position_type]
|
232
|
+
else
|
233
|
+
return [nil] * 4
|
234
|
+
end
|
235
|
+
when :file
|
236
|
+
## filename = canonic_file(info.container)
|
236
237
|
filename = info.container
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
238
|
+
# cm =
|
239
|
+
# if canonic_file(@frame.file) == filename
|
240
|
+
# cm = @frame.method
|
241
|
+
# if :line == info.position_type
|
242
|
+
# find_method_with_line(cm, info.position)
|
243
|
+
# end
|
244
|
+
# else
|
245
|
+
# LineCache.compiled_method(filename)
|
246
|
+
# end
|
247
|
+
return nil, filename, info.position, info.position_type
|
248
|
+
when nil
|
249
|
+
if [:line, :offset].member?(info.position_type)
|
250
|
+
## filename = @frame.file
|
251
|
+
# cm = @frame.method
|
252
|
+
# if :line == info.position_type
|
253
|
+
# cm = find_method_with_line(cm, info.position)
|
254
|
+
# end
|
255
|
+
return [nil, nil, info.position, info.position_type]
|
256
|
+
elsif !info.position_type
|
257
|
+
errmsg "Can't parse #{arg} as a position"
|
258
|
+
return [nil] * 4
|
259
|
+
else
|
260
|
+
errmsg "Unknown position type #{info.position_type} for location #{arg}"
|
261
|
+
return [nil] * 4
|
262
|
+
end
|
258
263
|
else
|
259
|
-
errmsg "Unknown
|
260
|
-
return [nil]
|
264
|
+
errmsg "Unknown container type #{info.container_type} for location #{arg}"
|
265
|
+
return [nil] * 4
|
261
266
|
end
|
262
|
-
else
|
263
|
-
errmsg "Unknown container type #{info.container_type} for location #{arg}"
|
264
|
-
return [nil] * 4
|
265
267
|
end
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
268
|
+
|
269
|
+
def parse_method(meth_str)
|
270
|
+
begin
|
271
|
+
meth_for_string(meth_str, @frame.binding)
|
272
|
+
rescue NameError
|
273
|
+
nil
|
274
|
+
rescue
|
275
|
+
nil
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def validate_initialize
|
280
|
+
## top_srcdir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
281
|
+
## @dbgr_script_iseqs, @dbgr_iseqs = filter_scripts(top_srcdir)
|
282
|
+
@file_exists_proc = Proc.new {|filename|
|
283
|
+
if LineCache.cached?(filename) || LineCache.cached_script?(filename) ||
|
284
|
+
(File.readable?(filename) && !File.directory?(filename))
|
285
|
+
true
|
286
|
+
## else
|
287
|
+
## find_load_path(filename)
|
288
|
+
end
|
289
|
+
}
|
275
290
|
end
|
276
291
|
end
|
277
|
-
|
278
|
-
def validate_initialize
|
279
|
-
## top_srcdir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
280
|
-
## @dbgr_script_iseqs, @dbgr_iseqs = filter_scripts(top_srcdir)
|
281
|
-
@file_exists_proc = Proc.new {|filename|
|
282
|
-
if LineCache.cached?(filename) || LineCache.cached_script?(filename) ||
|
283
|
-
(File.readable?(filename) && !File.directory?(filename))
|
284
|
-
true
|
285
|
-
## else
|
286
|
-
## find_load_path(filename)
|
287
|
-
end
|
288
|
-
}
|
289
292
|
end
|
290
|
-
end
|
291
293
|
|
292
294
|
if __FILE__ == $0
|
293
295
|
# Demo it.
|
294
296
|
# FIXME have to pull in main for its initalize routine
|
295
297
|
DIRNAME = File.dirname(__FILE__)
|
296
298
|
load File.join(DIRNAME, 'main.rb')
|
297
|
-
|
299
|
+
|
298
300
|
require_relative 'mock'
|
299
301
|
dbgr, cmd = MockDebugger::setup('exit', false)
|
300
302
|
cmdproc = cmd.proc
|
@@ -5,13 +5,11 @@
|
|
5
5
|
require 'set'
|
6
6
|
|
7
7
|
require 'rubygems'; require 'require_relative'
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
# frame hook msg running stepping validate).each do
|
12
|
-
%w(default display eval eventbuf frame hook load_cmds location msg running validate).each do
|
8
|
+
# Other debuggers have in addition: breakpoint disassemble stepping
|
9
|
+
%w(default display eval eventbuf frame hook load_cmds location msg running
|
10
|
+
validate).each do
|
13
11
|
|mod_str|
|
14
|
-
require_relative mod_str
|
12
|
+
require_relative File.join('processor', mod_str);
|
15
13
|
end
|
16
14
|
## require_relative '../app/brkptmgr'
|
17
15
|
|
@@ -43,6 +41,7 @@ module Trepan
|
|
43
41
|
attr_accessor :event # Stop event
|
44
42
|
attr_reader :intf # Current interface
|
45
43
|
# Trepan::Core instance)
|
44
|
+
attr_reader :interfaces # Array of all interfaces
|
46
45
|
attr_accessor :leave_cmd_loop # Commands set this to signal to leave
|
47
46
|
# the command loop (which often continues to
|
48
47
|
# run the debugged program).
|
@@ -65,34 +64,6 @@ module Trepan
|
|
65
64
|
# [location, container, stack_size,
|
66
65
|
# current_thread, pc_offset]
|
67
66
|
|
68
|
-
unless defined?(EVENT2ICON)
|
69
|
-
# Event icons used in printing locations.
|
70
|
-
EVENT2ICON = {
|
71
|
-
'brkpt' => 'xx',
|
72
|
-
'tbrkpt' => 'x1',
|
73
|
-
'c-call' => 'C>',
|
74
|
-
'c-return' => '<C',
|
75
|
-
'step-call' => '->',
|
76
|
-
'call' => '->',
|
77
|
-
'class' => '::',
|
78
|
-
'coverage' => '[]',
|
79
|
-
'debugger-call' => ':o',
|
80
|
-
'end' => '-|',
|
81
|
-
'line' => '--',
|
82
|
-
'raise' => '!!',
|
83
|
-
'return' => '<-',
|
84
|
-
'start' => '>>',
|
85
|
-
'switch' => 'sw',
|
86
|
-
'trace-var' => '$V',
|
87
|
-
'unknown' => '?!',
|
88
|
-
'vm' => 'VM',
|
89
|
-
'vm-insn' => '..',
|
90
|
-
}
|
91
|
-
# These events are important enough event that we always want to
|
92
|
-
# stop on them.
|
93
|
-
UNMASKABLE_EVENTS = Set.new(['end', 'raise', 'unknown'])
|
94
|
-
end
|
95
|
-
|
96
67
|
## def initialize(dbgr, settings={})
|
97
68
|
def initialize(interfaces, settings={})
|
98
69
|
@cmd_queue = []
|
@@ -134,6 +105,8 @@ module Trepan
|
|
134
105
|
self.send("#{submod}_initialize")
|
135
106
|
end
|
136
107
|
hook_initialize(commands)
|
108
|
+
unconditional_prehooks.insert_if_new(-1, *@trace_hook) if
|
109
|
+
@settings[:traceprint]
|
137
110
|
end
|
138
111
|
|
139
112
|
def compute_prompt
|
@@ -202,11 +175,7 @@ module Trepan
|
|
202
175
|
@cmd_queue.shift
|
203
176
|
end
|
204
177
|
if @current_command.empty?
|
205
|
-
|
206
|
-
@current_command = @last_command
|
207
|
-
else
|
208
|
-
next
|
209
|
-
end
|
178
|
+
next unless @last_command && intf.interactive?;
|
210
179
|
end
|
211
180
|
next if @current_command[0..0] == '#' # Skip comment lines
|
212
181
|
break
|
@@ -242,6 +211,11 @@ module Trepan
|
|
242
211
|
frame_setup(@context, @state)
|
243
212
|
|
244
213
|
@unconditional_prehooks.run
|
214
|
+
if @settings[:traceprint]
|
215
|
+
step
|
216
|
+
return
|
217
|
+
end
|
218
|
+
|
245
219
|
if breakpoint?
|
246
220
|
delete_breakpoint(@brkpt) if @brkpt.temp?
|
247
221
|
@last_pos = [@frame.vm_location, @stack_size, @current_thread, @event]
|
@@ -262,7 +236,7 @@ module Trepan
|
|
262
236
|
@prompt = compute_prompt
|
263
237
|
|
264
238
|
@leave_cmd_loop = false
|
265
|
-
print_location
|
239
|
+
print_location
|
266
240
|
# if 'trace-var' == @event
|
267
241
|
# msg "Note: we are stopped *after* the above location."
|
268
242
|
# end
|
@@ -283,6 +257,10 @@ module Trepan
|
|
283
257
|
# @event = @core.event
|
284
258
|
|
285
259
|
@unconditional_prehooks.run
|
260
|
+
if @settings[:traceprint]
|
261
|
+
step
|
262
|
+
return
|
263
|
+
end
|
286
264
|
# if breakpoint?
|
287
265
|
# @last_pos = [@frame.source_container, frame_line,
|
288
266
|
# @stack_size, @current_thread, @event,
|
@@ -294,7 +272,7 @@ module Trepan
|
|
294
272
|
@prompt = compute_prompt
|
295
273
|
|
296
274
|
@leave_cmd_loop = false
|
297
|
-
print_location
|
275
|
+
print_location
|
298
276
|
# if 'trace-var' == @event
|
299
277
|
# msg "Note: we are stopped *after* the above location."
|
300
278
|
# end
|
@@ -413,7 +391,7 @@ end
|
|
413
391
|
|
414
392
|
if __FILE__ == $0
|
415
393
|
$0 = 'foo' # So we don't get here again
|
416
|
-
require_relative '
|
394
|
+
require_relative 'lib/trepanning'
|
417
395
|
puts "To be continued...."
|
418
396
|
exit
|
419
397
|
dbg = Trepan.new(:nx => true)
|