| Class | Debugger::CommandProcessor |
| In: |
cli/ruby-debug/processor.rb
|
| Parent: | Processor |
A Debugger::CommandProcessor is the kind of Debugger::Processor used when you are running inside the same process as the debugged program.
| display | [R] |
Regularize or "canonicalize" file name filename. This is also used as a common funnel place if basename is desired or if we are working remotely and want to change the basename. Or we are eliding filenames.
# File cli/ruby-debug/processor.rb, line 103
103: def self.canonic_file(filename)
104: # For now we want resolved filenames
105: if Command.settings[:basename]
106: File.basename(filename)
107: else
108: # Cache this?
109: Pathname.new(filename).cleanpath.to_s
110: end
111: end
# File cli/ruby-debug/processor.rb, line 76
76: def initialize(interface = LocalInterface.new)
77: @interface = interface
78: @commands = []
79: @display = []
80:
81: @mutex = Mutex.new
82: @last_cmd = nil
83: @last_file = nil # Filename the last time we stopped
84: @last_line = nil # line number the last time we stopped
85: @debugger_breakpoints_were_empty = false # Show breakpoints 1st time
86: @debugger_displays_were_empty = true # No display 1st time
87: @debugger_context_was_dead = true # Assume we haven't started.
88: end
# File cli/ruby-debug/processor.rb, line 113
113: def self.print_location_and_text(file, line)
114: file_line = "%s:%s\n%s" % [canonic_file(file), line,
115: Debugger.line_at(file, line)]
116: # FIXME: use annotations routines
117: if Debugger.annotate.to_i > 2
118: file_line = "\032\032source #{file_line}"
119: elsif Debugger.inside_emacs?
120: file_line = "\032\032#{file_line}"
121: end
122: print file_line
123: end
Create a "protected" version of method mname. A protected method handles all unhandled exceptions that would cause the program to terminate.
# File cli/ruby-debug/processor.rb, line 128
128: def self.protect(mname)
129: alias_method "__#{mname}", mname
130: module_eval %{
131: def #{mname}(*args)
132: @mutex.synchronize do
133: return unless @interface
134: __#{mname}(*args)
135: end
136: rescue IOError, Errno::EPIPE
137: self.interface = nil
138: rescue SignalException
139: raise
140: rescue Exception
141: print "INTERNAL ERROR!!! #\{$!\}\n" rescue nil
142: print $!.backtrace.map{|l| "\t#\{l\}"}.join("\n") rescue nil
143: end
144: }
145: end
This is a callback routine when the debugged program hits a breakpoint event. For example ruby-debug-base calls this.
# File cli/ruby-debug/processor.rb, line 149
149: def at_breakpoint(context, breakpoint)
150: aprint 'stopped' if Debugger.annotate.to_i > 2
151: n = Debugger.breakpoints.index(breakpoint) + 1
152: file = CommandProcessor.canonic_file(breakpoint.source)
153: line = breakpoint.pos
154: if Debugger.annotate.to_i > 2
155: print afmt("source #{file}:#{line}")
156: end
157: print "Breakpoint %d at %s:%s\n", n, file, line
158: end
This is a callback routine when the debugged program hits a catchpoint. For example ruby-debug-base calls this.
# File cli/ruby-debug/processor.rb, line 163
163: def at_catchpoint(context, excpt)
164: aprint 'stopped' if Debugger.annotate.to_i > 2
165: file = CommandProcessor.canonic_file(context.frame_file(0))
166: line = context.frame_line(0)
167: print afmt("%s:%d" % [file, line]) if Debugger.inside_emacs?
168: print "Catchpoint at %s:%d: `%s' (%s)\n", file, line, excpt, excpt.class
169: fs = context.stack_size
170: tb = caller(0)[-fs..-1]
171: if tb
172: for i in tb
173: print "\tfrom %s\n", i
174: end
175: end
176: end
This is a callback routine when the debugged program hits a "line" (or statement boundary) event. For example ruby-debug-base calls this.
# File cli/ruby-debug/processor.rb, line 198
198: def at_line(context, file, line)
199: process_commands(context, file, line)
200: end
This is a callback routine when the debugged program hits a "return" event. For example ruby-debug-base calls this. Note: right now ruby-debug-base does not call this. Perhaps other bases routines such as the one in JRuby do.
# File cli/ruby-debug/processor.rb, line 207
207: def at_return(context, file, line)
208: context.stop_frame = -1
209: process_commands(context, file, line)
210: end
# File cli/ruby-debug/processor.rb, line 179
179: def at_tracing(context, file, line)
180: return if defined?(Debugger::RDEBUG_FILE) &&
181: Debugger::RDEBUG_FILE == file # Don't trace ourself
182: @last_file = CommandProcessor.canonic_file(file)
183: file = CommandProcessor.canonic_file(file)
184: unless file == @last_file and @last_line == line and
185: Command.settings[:tracing_plus]
186: print "Tracing(%d):%s:%s %s",
187: context.thnum, file, line, Debugger.line_at(file, line)
188: @last_file = file
189: @last_line = line
190: end
191: always_run(context, file, line, 2)
192: end
# File cli/ruby-debug/processor.rb, line 90
90: def interface=(interface)
91: @mutex.synchronize do
92: @interface.close if @interface
93: @interface = interface
94: end
95: end
Return the command object to run given input string input.
# File cli/ruby-debug/processor.rb, line 213
213: def lookup(input)
214: @commands.find{ |c| c.match(input) }
215: end
Run a single command specified by string input; commands is and Array of possible debugger command objects and context is a Debugger::Context object.
# File cli/ruby-debug/processor.rb, line 220
220: def one_cmd(commands, context, input)
221: if cmd = lookup(input)
222: if context.dead? && cmd.class.need_context
223: p cmd
224: print "Command is unavailable\n"
225: else
226: cmd.execute
227: end
228: else
229: unknown_cmd = commands.find{|cmd| cmd.class.unknown }
230: if unknown_cmd
231: unknown_cmd.execute
232: else
233: errmsg "Unknown command: \"#{input}\". Try \"help\".\n"
234: end
235: end
236: end