rb8-trepanning 0.1.3 → 0.1.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/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)
|