trepanning 1.93.35 → 2.15.33
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ChangeLog +491 -55
- data/LICENSE +1 -1
- data/NEWS +18 -14
- data/README.md +5 -22
- data/Rakefile +22 -1
- data/app/breakpoint.rb +5 -3
- data/app/core.rb +147 -179
- data/app/default.rb +47 -46
- data/app/file.rb +6 -7
- data/app/frame.rb +183 -176
- data/app/markdown.rb +2 -9
- data/app/options.rb +1 -1
- data/app/run.rb +71 -37
- data/interface/script.rb +8 -8
- data/io.rb +19 -20
- data/lib/trepanning.rb +292 -297
- data/processor.rb +332 -344
- data/processor/breakpoint.rb +98 -96
- data/processor/command/base/submgr.rb +9 -9
- data/processor/command/break.rb +40 -38
- data/processor/command/continue.rb +15 -10
- data/processor/command/debug.rb +6 -25
- data/processor/command/delete.rb +21 -12
- data/processor/command/directory.rb +15 -13
- data/processor/command/disable.rb +12 -9
- data/processor/command/disassemble.rb +80 -74
- data/processor/command/display.rb +15 -12
- data/processor/command/down.rb +8 -3
- data/processor/command/edit.rb +37 -23
- data/processor/command/enable.rb +11 -8
- data/processor/command/eval.rb +24 -22
- data/processor/command/finish.rb +50 -48
- data/processor/command/help.rb +1 -1
- data/processor/command/info_subcmd/breakpoints.rb +7 -7
- data/processor/command/info_subcmd/files.rb +195 -196
- data/processor/command/info_subcmd/frame.rb +7 -4
- data/processor/command/info_subcmd/locals.rb +29 -12
- data/processor/command/info_subcmd/program.rb +48 -39
- data/processor/command/info_subcmd/registers_subcmd/ep.rb +46 -0
- data/processor/command/info_subcmd/registers_subcmd/helper.rb +32 -35
- data/processor/command/info_subcmd/registers_subcmd/sp.rb +29 -23
- data/processor/command/info_subcmd/return.rb +28 -10
- data/processor/command/info_subcmd/variables_subcmd/class.rb +3 -3
- data/processor/command/info_subcmd/variables_subcmd/constants.rb +77 -0
- data/processor/command/info_subcmd/variables_subcmd/globals.rb +7 -7
- data/processor/command/info_subcmd/variables_subcmd/instance.rb +68 -22
- data/processor/command/info_subcmd/variables_subcmd/locals.rb +148 -67
- data/processor/command/list.rb +14 -8
- data/processor/command/macro.rb +1 -1
- data/processor/command/next.rb +1 -0
- data/processor/command/set_subcmd/auto.rb +3 -3
- data/processor/command/set_subcmd/different.rb +30 -29
- data/processor/command/set_subcmd/events.rb +74 -48
- data/processor/command/set_subcmd/max_subcmd/list.rb +12 -5
- data/processor/command/set_subcmd/max_subcmd/width.rb +28 -19
- data/processor/command/set_subcmd/register.rb +37 -0
- data/processor/command/set_subcmd/register_subcmd/pc.rb +67 -0
- data/processor/command/set_subcmd/register_subcmd/sp.rb +75 -0
- data/processor/command/set_subcmd/reload.rb +12 -10
- data/processor/command/set_subcmd/return.rb +68 -44
- data/processor/command/shell.rb +3 -2
- data/processor/command/show_subcmd/different.rb +17 -14
- data/processor/command/show_subcmd/events.rb +25 -25
- data/processor/default.rb +1 -1
- data/processor/eval.rb +14 -15
- data/processor/frame.rb +43 -36
- data/processor/help.rb +5 -5
- data/processor/hook.rb +26 -29
- data/processor/location.rb +54 -51
- data/processor/mock.rb +4 -3
- data/processor/running.rb +113 -103
- data/processor/validate.rb +401 -373
- data/test/data/debug.cmd +8 -0
- data/test/data/debug.right +13 -0
- data/test/data/debugger-stop.right +6 -4
- data/test/data/fname-with-blank.cmd +1 -1
- data/test/data/fname-with-blank.right +5 -0
- data/test/data/pc.cmd +8 -0
- data/test/data/pc.right +10 -0
- data/test/data/quit.right +3 -1
- data/test/data/trace.cmd +2 -2
- data/test/data/trace.right +41 -20
- data/test/example/assign.rb +6 -0
- data/test/functional/fn_helper.rb +11 -17
- data/test/functional/test-break-long.rb +15 -16
- data/test/functional/test-break.rb +6 -8
- data/test/functional/test-condition.rb +8 -10
- data/test/functional/test-debugger-call-bug.rb +21 -22
- data/test/functional/test-delete.rb +57 -59
- data/test/functional/test-eval.rb +101 -103
- data/test/functional/test-finish.rb +24 -33
- data/test/functional/test-immediate-step-bug.rb +6 -10
- data/test/functional/test-next.rb +64 -65
- data/test/functional/test-raise.rb +63 -64
- data/test/functional/test-recursive-bt.rb +81 -76
- data/test/functional/test-remap.rb +6 -7
- data/test/functional/test-return.rb +44 -38
- data/test/functional/test-step.rb +55 -53
- data/test/functional/test-stepbug.rb +6 -9
- data/test/functional/test-watchg.rb +40 -39
- data/test/integration/test-debug.rb +12 -0
- data/test/integration/test-debugger-stop.rb +7 -7
- data/test/integration/test-pc.rb +24 -0
- data/test/integration/test-trace.rb +1 -1
- data/test/unit/cmd-helper.rb +0 -1
- data/test/unit/test-app-brkpt.rb +21 -21
- data/test/unit/test-app-brkptmgr.rb +7 -8
- data/test/unit/test-app-display.rb +3 -4
- data/test/unit/test-app-frame.rb +4 -5
- data/test/unit/test-base-subsubcmd.rb +2 -2
- data/test/unit/test-cmd-break.rb +6 -6
- data/test/unit/test-cmd-endisable.rb +7 -6
- data/test/unit/test-cmd-parse_list_cmd.rb +24 -24
- data/test/unit/test-io-tcpserver.rb +39 -35
- data/test/unit/test-proc-default.rb +23 -22
- data/test/unit/test-proc-eval.rb +1 -2
- data/test/unit/test-proc-frame.rb +8 -9
- data/test/unit/test-proc-list.rb +1 -1
- data/test/unit/test-proc-location.rb +2 -2
- data/test/unit/test-proc-main.rb +10 -10
- data/test/unit/test-proc-validate.rb +11 -13
- data/test/unit/test-subcmd-help.rb +1 -2
- data/trepanning.gemspec +8 -13
- metadata +44 -95
- data/COPYING +0 -57
- data/data/custom_require.rb +0 -44
- data/data/perldb.bindings +0 -17
- data/data/prelude.rb +0 -38
- data/processor/command/info_subcmd/variables_subcmd/constant.rb +0 -41
- data/processor/command/raise.rb +0 -48
- data/processor/command/set_subcmd/pc.rb +0 -62
- data/processor/command/set_subcmd/sp.rb +0 -67
- data/processor/eventbuf.rb +0 -133
data/processor.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# The main "driver" class for a command processor. Other parts of the
|
3
3
|
# command class and debugger command objects are pulled in from here.
|
4
4
|
|
5
|
-
%w(default breakpoint complete display
|
5
|
+
%w(default breakpoint complete display eval load_cmds location
|
6
6
|
frame hook msg running validate).each do
|
7
7
|
|mod_str|
|
8
8
|
require_relative "processor/#{mod_str}"
|
@@ -14,375 +14,363 @@ class Trepan
|
|
14
14
|
|
15
15
|
# SEE ALSO attr's in require_relative's of loop above.
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
17
|
+
attr_reader :cmd_argstr # Current command args, a String.
|
18
|
+
# This is current_command with the command
|
19
|
+
# name removed from the beginning.
|
20
|
+
attr_reader :cmd_name # command name before alias or macro resolution
|
21
|
+
attr_reader :cmd_queue # queue of commands to run
|
22
|
+
attr_reader :core # Trepan core object
|
23
|
+
attr_reader :current_command # Current command getting run, a String.
|
24
|
+
attr_reader :dbgr # Trepan instance (via
|
25
|
+
# Trepan::Core instance)
|
26
|
+
attr_accessor :debug_nest # Number of nested debugs. Used in showing
|
27
|
+
# prompt.
|
28
|
+
attr_accessor :different_pos # Same type as settings[:different]
|
29
|
+
# this is the temporary value for the
|
30
|
+
# next stop while settings is the default
|
31
|
+
# value to use.
|
32
|
+
attr_accessor :event # Stop event. Same as @core.event
|
33
|
+
attr_reader :intf # Current interface
|
34
|
+
# Trepan::Core instance)
|
35
|
+
attr_reader :interfaces # Array of all interfaces
|
36
|
+
attr_accessor :leave_cmd_loop # Commands set this to signal to leave
|
37
|
+
# the command loop (which often continues to
|
38
|
+
# run the debugged program).
|
39
|
+
attr_accessor :line_no # Last line shown in "list" command
|
40
|
+
attr_accessor :next_level # Fixnum. frame.stack_size has to
|
41
|
+
# be <= than this. If next'ing,
|
42
|
+
# this will be > 0.
|
43
|
+
attr_accessor :next_thread # Thread. If non-nil then in
|
44
|
+
# stepping the thread has to be
|
45
|
+
# this thread.
|
46
|
+
attr_accessor :pass_exception # Pass an exception back
|
47
|
+
attr_accessor :prompt # String print before requesting input
|
48
|
+
attr_reader :settings # Hash[:symbol] of command
|
49
|
+
# processor settings
|
50
|
+
|
51
|
+
attr_accessor :traced_vars # list of traced global variables
|
52
|
+
|
53
|
+
# The following are used in to force stopping at a different line
|
54
|
+
# number. FIXME: could generalize to a position object.
|
55
|
+
attr_accessor :last_pos # Last position. 6-Tuple: of
|
56
|
+
# [location, container, stack_size,
|
57
|
+
# current_thread, pc_offset]
|
58
|
+
|
59
|
+
|
60
|
+
def initialize(core, settings={})
|
61
|
+
@cmd_queue = []
|
62
|
+
@core = core
|
63
|
+
@debug_nest = 1
|
64
|
+
@dbgr = core.dbgr
|
65
|
+
@hidelevels = {}
|
66
|
+
@interfaces = @dbgr.intf
|
67
|
+
@last_command = nil
|
68
|
+
@last_pos = [nil, nil, nil, nil, nil, nil]
|
69
|
+
@next_level = 32000
|
70
|
+
@next_thread = nil
|
71
|
+
|
72
|
+
start_cmds = settings.delete(:start_cmds)
|
73
|
+
start_file = settings.delete(:start_file)
|
74
|
+
|
75
|
+
@settings = DEFAULT_SETTINGS.merge(settings)
|
76
|
+
@traced_vars = {}
|
77
|
+
@different_pos = @settings[:different]
|
78
|
+
|
79
|
+
# Start with empty thread and frame info.
|
80
|
+
frame_teardown
|
81
|
+
|
82
|
+
# Run initialization routines for each of the "submodule"s.
|
83
|
+
# load_cmds has to come first.
|
84
|
+
%w(load_cmds breakpoint display frame running validate).each do |submod|
|
85
|
+
self.send("#{submod}_initialize")
|
86
|
+
end
|
87
|
+
hook_initialize(commands)
|
88
|
+
unconditional_prehooks.insert_if_new(-1, *trace_hook) if
|
89
|
+
@settings[:traceprint]
|
90
|
+
end
|
91
|
+
|
92
|
+
def compute_prompt
|
93
|
+
thread_str =
|
94
|
+
if @event == 'post-mortem'
|
95
|
+
':pm'
|
96
|
+
elsif 1 == Thread.list.size
|
97
|
+
''
|
98
|
+
elsif Thread.current == Thread.main
|
99
|
+
'@main'
|
100
|
+
else
|
101
|
+
"@#{Thread.current.object_id}"
|
102
|
+
end
|
103
|
+
"%s#{settings[:prompt]}%s%s: " %
|
104
|
+
['(' * @debug_nest, thread_str, ')' * @debug_nest]
|
104
105
|
|
105
|
-
def compute_prompt
|
106
|
-
thread_str =
|
107
|
-
if 1 == Thread.list.size
|
108
|
-
''
|
109
|
-
elsif Thread.current == Thread.main
|
110
|
-
'@main'
|
111
|
-
else
|
112
|
-
"@#{Thread.current.object_id}"
|
113
106
|
end
|
114
|
-
"%s#{settings[:prompt]}%s%s: " %
|
115
|
-
['(' * @debug_nest, thread_str, ')' * @debug_nest]
|
116
107
|
|
117
|
-
|
108
|
+
def finalize
|
109
|
+
breakpoint_finalize
|
110
|
+
msg "%sThat's all, folks..." %
|
111
|
+
(defined?(Trepan::PROGRAM) ? "#{Trepan::PROGRAM}: " : '')
|
112
|
+
end
|
118
113
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
114
|
+
# Check that we meed the criteria that cmd specifies it needs
|
115
|
+
def ok_for_running(cmd, name, nargs)
|
116
|
+
# TODO check execution_set against execution status.
|
117
|
+
# Check we have frame is not null
|
118
|
+
min_args = cmd.class.const_get(:MIN_ARGS)
|
119
|
+
if nargs < min_args
|
120
|
+
errmsg(("Command '%s' needs at least %d argument(s); " +
|
121
|
+
"got %d.") % [name, min_args, nargs])
|
122
|
+
return false
|
123
|
+
end
|
124
|
+
max_args = cmd.class.const_get(:MAX_ARGS)
|
125
|
+
if max_args and nargs > max_args
|
126
|
+
errmsg(("Command '%s' needs at most %d argument(s); " +
|
127
|
+
"got %d.") % [name, max_args, nargs])
|
128
|
+
return false
|
129
|
+
end
|
130
|
+
# if cmd.class.const_get(:NEED_RUNNING) && !...
|
131
|
+
# errmsg "Command '%s' requires a running program." % name
|
132
|
+
# return false
|
133
|
+
# end
|
134
|
+
|
135
|
+
if cmd.class.const_get(:NEED_STACK) && !@frame
|
136
|
+
errmsg "Command '%s' requires a running stack frame." % name
|
137
|
+
return false
|
138
|
+
end
|
124
139
|
|
125
|
-
|
126
|
-
|
127
|
-
# TODO check execution_set against execution status.
|
128
|
-
# Check we have frame is not null
|
129
|
-
min_args = cmd.class.const_get(:MIN_ARGS)
|
130
|
-
if nargs < min_args
|
131
|
-
errmsg(("Command '%s' needs at least %d argument(s); " +
|
132
|
-
"got %d.") % [name, min_args, nargs])
|
133
|
-
return false
|
134
|
-
end
|
135
|
-
max_args = cmd.class.const_get(:MAX_ARGS)
|
136
|
-
if max_args and nargs > max_args
|
137
|
-
errmsg(("Command '%s' needs at most %d argument(s); " +
|
138
|
-
"got %d.") % [name, max_args, nargs])
|
139
|
-
return false
|
140
|
-
end
|
141
|
-
# if cmd.class.const_get(:NEED_RUNNING) && !...
|
142
|
-
# errmsg "Command '%s' requires a running program." % name
|
143
|
-
# return false
|
144
|
-
# end
|
145
|
-
|
146
|
-
if cmd.class.const_get(:NEED_STACK) && !@frame
|
147
|
-
errmsg "Command '%s' requires a running stack frame." % name
|
148
|
-
return false
|
149
|
-
end
|
150
|
-
|
151
|
-
return true
|
152
|
-
end
|
140
|
+
return true
|
141
|
+
end
|
153
142
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
143
|
+
# Run one debugger command. True is returned if we want to quit.
|
144
|
+
def process_command_and_quit?()
|
145
|
+
intf_size = @dbgr.intf.size
|
146
|
+
@intf = @dbgr.intf[-1]
|
147
|
+
return true if @intf.input_eof? && intf_size == 1
|
148
|
+
while intf_size > 1 || !@intf.input_eof?
|
149
|
+
begin
|
150
|
+
@current_command =
|
151
|
+
if @cmd_queue.empty?
|
152
|
+
# Leave trailing blanks on for the "complete" command
|
153
|
+
read_command.chomp
|
154
|
+
else
|
155
|
+
@cmd_queue.shift
|
156
|
+
end
|
157
|
+
if @current_command.empty?
|
158
|
+
next unless @last_command && intf.interactive?;
|
159
|
+
end
|
160
|
+
next if @current_command[0..0] == '#' # Skip comment lines
|
161
|
+
break
|
162
|
+
rescue IOError, Errno::EPIPE => e
|
163
|
+
if intf_size > 1
|
164
|
+
@dbgr.intf.pop
|
165
|
+
intf_size = @dbgr.intf.size
|
166
|
+
@intf = @dbgr.intf[-1]
|
167
|
+
@last_command = nil
|
168
|
+
print_location
|
165
169
|
else
|
166
|
-
|
170
|
+
## FIXME: think of something better.
|
171
|
+
quit('quit!')
|
172
|
+
return true
|
167
173
|
end
|
168
|
-
if @current_command.empty?
|
169
|
-
next unless @last_command && intf.interactive?
|
170
|
-
@current_command = @last_command
|
171
174
|
end
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
175
|
+
end
|
176
|
+
run_command(@current_command)
|
177
|
+
|
178
|
+
# Save it to the history.
|
179
|
+
@intf.history_io.puts @last_command if @last_command && @intf.history_io
|
180
|
+
end
|
181
|
+
|
182
|
+
# This is the main entry point.
|
183
|
+
def process_commands(frame, top_skip=0)
|
184
|
+
|
185
|
+
@event = frame ? @core.event : 'post-mortem'
|
186
|
+
|
187
|
+
frame_setup(frame, top_skip)
|
188
|
+
|
189
|
+
@unconditional_prehooks.run
|
190
|
+
|
191
|
+
if 'trace-var' == @event
|
192
|
+
variable_name, value = @core.hook_arg
|
193
|
+
action = @traced_vars[variable_name]
|
194
|
+
msg "trace: #{variable_name} = #{value}"
|
195
|
+
case action
|
196
|
+
when nil
|
197
|
+
errmsg "No action recorded for variable. Using 'stop'."
|
198
|
+
when 'stop'
|
199
|
+
# msg "Note: we are stopped *after* the above location."
|
200
|
+
when 'nostop'
|
180
201
|
print_location
|
202
|
+
return
|
181
203
|
else
|
182
|
-
|
183
|
-
|
184
|
-
|
204
|
+
errmsg "Internal error: unknown trace_var action #{action}"
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
if breakpoint?
|
209
|
+
@last_pos = [@frame.source_container, frame_line,
|
210
|
+
@stack_size, @current_thread, @event,
|
211
|
+
@frame.pc_offset]
|
212
|
+
elsif @event != 'post-mortem'
|
213
|
+
return if stepping_skip? || @stack_size <= @hide_level
|
214
|
+
if @settings[:traceprint]
|
215
|
+
step
|
216
|
+
return
|
217
|
+
end
|
218
|
+
end
|
219
|
+
@prompt = compute_prompt
|
220
|
+
|
221
|
+
@leave_cmd_loop = false
|
222
|
+
|
223
|
+
print_location unless @settings[:traceprint] || @event == 'post-mortem'
|
224
|
+
|
225
|
+
@cmdloop_prehooks.run
|
226
|
+
while not @leave_cmd_loop do
|
227
|
+
begin
|
228
|
+
break if process_command_and_quit?()
|
229
|
+
rescue SystemExit
|
230
|
+
@dbgr.stop
|
231
|
+
raise
|
232
|
+
rescue Exception => exc
|
233
|
+
# If we are inside the script interface errmsg may fail.
|
234
|
+
begin
|
235
|
+
errmsg("Internal debugger error: #{exc.inspect}")
|
236
|
+
rescue IOError
|
237
|
+
$stderr.puts "Internal debugger error: #{exc.inspect}"
|
238
|
+
end
|
239
|
+
exception_dump(exc, @settings[:debugexcept], $!.backtrace)
|
185
240
|
end
|
186
241
|
end
|
242
|
+
@cmdloop_posthooks.run
|
187
243
|
end
|
188
|
-
run_command(@current_command)
|
189
244
|
|
190
|
-
#
|
191
|
-
|
192
|
-
|
245
|
+
# Run current_command, a String. @last_command is set after the
|
246
|
+
# command is run if it is a command.
|
247
|
+
def run_command(current_command)
|
248
|
+
eval_command =
|
249
|
+
if current_command[0..0] == '!'
|
250
|
+
current_command[0] = ''
|
251
|
+
else
|
252
|
+
false
|
253
|
+
end
|
193
254
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
@stack_size, @current_thread, @event,
|
222
|
-
@frame.pc_offset]
|
223
|
-
elsif @event != 'post-mortem'
|
224
|
-
return if stepping_skip? || @stack_size <= @hide_level
|
225
|
-
if @settings[:traceprint]
|
226
|
-
step
|
227
|
-
return
|
228
|
-
end
|
229
|
-
end
|
230
|
-
@prompt = compute_prompt
|
231
|
-
|
232
|
-
@leave_cmd_loop = false
|
233
|
-
|
234
|
-
print_location unless @settings[:traceprint]
|
235
|
-
@eventbuf.add_mark if @settings[:tracebuffer]
|
236
|
-
|
237
|
-
@cmdloop_prehooks.run
|
238
|
-
while not @leave_cmd_loop do
|
239
|
-
begin
|
240
|
-
break if process_command_and_quit?()
|
241
|
-
rescue SystemExit
|
242
|
-
@dbgr.stop
|
243
|
-
raise
|
244
|
-
rescue Exception => exc
|
245
|
-
# If we are inside the script interface errmsg may fail.
|
246
|
-
begin
|
247
|
-
errmsg("Internal debugger error: #{exc.inspect}")
|
248
|
-
rescue IOError
|
249
|
-
$stderr.puts "Internal debugger error: #{exc.inspect}"
|
250
|
-
end
|
251
|
-
exception_dump(exc, @settings[:debugexcept], $!.backtrace)
|
252
|
-
end
|
253
|
-
end
|
254
|
-
@cmdloop_posthooks.run
|
255
|
-
end
|
255
|
+
unless eval_command
|
256
|
+
commands = current_command.split(';;')
|
257
|
+
if commands.size > 1
|
258
|
+
current_command = commands.shift
|
259
|
+
@cmd_queue.unshift(*commands)
|
260
|
+
end
|
261
|
+
args = current_command.split
|
262
|
+
# Expand macros. FIXME: put in a procedure
|
263
|
+
while true do
|
264
|
+
macro_cmd_name = args[0]
|
265
|
+
return false if args.size == 0
|
266
|
+
break unless @macros.member?(macro_cmd_name)
|
267
|
+
current_command = @macros[macro_cmd_name][0].call(*args[1..-1])
|
268
|
+
msg current_command.inspect if settings[:debugmacro]
|
269
|
+
if current_command.is_a?(Array) &&
|
270
|
+
current_command.all? {|val| val.is_a?(String)}
|
271
|
+
args = (first=current_command.shift).split
|
272
|
+
@cmd_queue += current_command
|
273
|
+
current_command = first
|
274
|
+
elsif current_command.is_a?(String)
|
275
|
+
args = current_command.split
|
276
|
+
else
|
277
|
+
errmsg("macro #{macro_cmd_name} should return an Array " +
|
278
|
+
"of Strings or a String. Got #{current_command.inspect}")
|
279
|
+
return false
|
280
|
+
end
|
281
|
+
end
|
256
282
|
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
false
|
265
|
-
end
|
283
|
+
@cmd_name = args[0]
|
284
|
+
run_cmd_name =
|
285
|
+
if @aliases.member?(@cmd_name)
|
286
|
+
@aliases[@cmd_name]
|
287
|
+
else
|
288
|
+
@cmd_name
|
289
|
+
end
|
266
290
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
+
run_cmd_name = uniq_abbrev(@commands.keys, run_cmd_name) if
|
292
|
+
!@commands.member?(run_cmd_name) && @settings[:abbrev]
|
293
|
+
|
294
|
+
if @commands.member?(run_cmd_name)
|
295
|
+
cmd = @commands[run_cmd_name]
|
296
|
+
if ok_for_running(cmd, run_cmd_name, args.size-1)
|
297
|
+
@cmd_argstr = current_command[@cmd_name.size..-1].lstrip
|
298
|
+
cmd.run(args)
|
299
|
+
@last_command = current_command
|
300
|
+
end
|
301
|
+
return false
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
# Eval anything that's not a command or has been
|
306
|
+
# requested to be eval'd
|
307
|
+
if settings[:autoeval] || eval_command
|
308
|
+
# eval_code(current_command, @settings[:maxstring])
|
309
|
+
begin
|
310
|
+
msg 'D=> ' + debug_eval_with_exception(current_command).inspect
|
311
|
+
return false
|
312
|
+
rescue NameError
|
313
|
+
end
|
314
|
+
end
|
315
|
+
undefined_command(cmd_name)
|
291
316
|
return false
|
292
|
-
end
|
293
317
|
end
|
294
318
|
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
run_cmd_name = uniq_abbrev(@commands.keys, run_cmd_name) if
|
304
|
-
!@commands.member?(run_cmd_name) && @settings[:abbrev]
|
305
|
-
|
306
|
-
if @commands.member?(run_cmd_name)
|
307
|
-
cmd = @commands[run_cmd_name]
|
308
|
-
if ok_for_running(cmd, run_cmd_name, args.size-1)
|
309
|
-
@cmd_argstr = current_command[@cmd_name.size..-1].lstrip
|
310
|
-
cmd.run(args)
|
311
|
-
@last_command = current_command
|
312
|
-
end
|
313
|
-
return false
|
314
|
-
end
|
315
|
-
end
|
316
|
-
|
317
|
-
# Eval anything that's not a command or has been
|
318
|
-
# requested to be eval'd
|
319
|
-
if settings[:autoeval] || eval_command
|
320
|
-
# eval_code(current_command, @settings[:maxstring])
|
321
|
-
begin
|
322
|
-
msg 'D=> ' + debug_eval_with_exception(current_command).inspect
|
323
|
-
return false
|
324
|
-
rescue NameError
|
319
|
+
# Error message when a command doesn't exist
|
320
|
+
def undefined_command(cmd_name)
|
321
|
+
begin
|
322
|
+
errmsg('Undefined command: "%s". Try "help".' % cmd_name)
|
323
|
+
rescue
|
324
|
+
$stderr.puts 'Undefined command: "%s". Try "help".' % cmd_name
|
325
|
+
end
|
325
326
|
end
|
326
|
-
end
|
327
|
-
undefined_command(cmd_name)
|
328
|
-
return false
|
329
|
-
end
|
330
327
|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
end
|
328
|
+
# FIXME: Allow access to both Trepan::CmdProcessor and Trepan
|
329
|
+
# for index [] and []=.
|
330
|
+
# If there is a Trepan::CmdProcessor setting that would take precidence.
|
331
|
+
# def settings
|
332
|
+
# @settings.merge(@dbgr.settings) # wrong because this doesn't allow []=
|
333
|
+
# end
|
338
334
|
end
|
339
|
-
|
340
|
-
# FIXME: Allow access to both Trepan::CmdProcessor and Trepan
|
341
|
-
# for index [] and []=.
|
342
|
-
# If there is a Trepan::CmdProcessor setting that would take precidence.
|
343
|
-
# def settings
|
344
|
-
# @settings.merge(@dbgr.settings) # wrong because this doesn't allow []=
|
345
|
-
# end
|
346
|
-
end
|
347
335
|
end
|
348
336
|
|
349
337
|
if __FILE__ == $0
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
338
|
+
$0 = 'foo' # So we don't get here again
|
339
|
+
require_relative 'lib/trepanning'
|
340
|
+
dbg = Trepan.new(:nx => true)
|
341
|
+
dbg.core.processor.msg('I am main')
|
342
|
+
cmdproc = dbg.core.processor
|
343
|
+
cmdproc.errmsg('Whoa!')
|
344
|
+
cmds = cmdproc.commands
|
345
|
+
p cmdproc.aliases
|
346
|
+
p cmdproc.commands.keys.sort
|
347
|
+
cmd_name, cmd_obj = cmds.first
|
348
|
+
puts cmd_obj.class.const_get(:HELP)
|
349
|
+
puts cmd_obj.class.const_get(:SHORT_HELP)
|
350
|
+
|
351
|
+
puts cmdproc.compute_prompt
|
352
|
+
Thread.new{ puts cmdproc.compute_prompt }.join
|
353
|
+
|
354
|
+
th = Thread.new{ Thread.pass; x = 1 }
|
355
|
+
puts cmdproc.compute_prompt
|
356
|
+
th.join
|
357
|
+
cmdproc.debug_nest += 1
|
358
|
+
puts cmdproc.compute_prompt
|
359
|
+
|
360
|
+
|
361
|
+
if ARGV.size > 0
|
362
|
+
dbg.core.processor.msg('Enter "q" to quit')
|
363
|
+
dbg.proc_process_commands
|
364
|
+
else
|
365
|
+
$input = []
|
366
|
+
class << dbg.core.processor
|
367
|
+
def read_command
|
368
|
+
$input.shift
|
369
|
+
end
|
370
|
+
end
|
371
|
+
$input = ['1+2']
|
372
|
+
dbg.core.processor.process_command_and_quit?
|
373
|
+
$input = ['!s = 5'] # ! means eval line
|
374
|
+
dbg.core.processor.process_command_and_quit?
|
382
375
|
end
|
383
|
-
$input = ['1+2']
|
384
|
-
dbg.core.processor.process_command_and_quit?
|
385
|
-
$input = ['!s = 5'] # ! means eval line
|
386
|
-
dbg.core.processor.process_command_and_quit?
|
387
|
-
end
|
388
376
|
end
|