trepanning 1.93.35 → 2.15.33
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.
- 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
|