module Trepan
Attributes
gdb-style annotation mode. Used in GNU Emacs interface
If start_sentinal
is set, it is a string to look for in caller() and is used to see if the call stack is truncated. Is also defined in app/default.rb
in remote mode, wait for the remote connection
Public Class Methods
# File lib/trepanning.rb, line 223 def add_command_file(cmdfile, opts={}, stderr=$stderr) unless File.readable?(cmdfile) if File.exists?(cmdfile) stderr.puts "Command file '#{cmdfile}' is not readable." return else stderr.puts "Command file '#{cmdfile}' does not exist." return end end @@intf << Trepan::ScriptInterface.new(cmdfile, @output, opts) end
# File lib/trepanning.rb, line 236 def add_startup_files() seen = {} cwd_initfile = File.join('.', Trepan::CMD_INITFILE_BASE) [cwd_initfile, Trepan::CMD_INITFILE].each do |initfile| full_initfile_path = File.expand_path(initfile) next if seen[full_initfile_path] add_command_file(full_initfile_path) if File.readable?(full_initfile_path) seen[full_initfile_path] = true end end
FIXME: see if we can put this in app/complete.
The method is called when we want to do debugger command completion such as called from GNU Readline with <TAB>.
# File lib/trepanning.rb, line 21 def self.completion_method(last_token, leading=nil) if leading.nil? if Readline.respond_to?(:line_buffer) completion = Trepan.handler.cmdproc.complete(Readline.line_buffer, last_token) else completion = Trepan.handler.cmdproc.complete(last_token, '') end else completion = Trepan.handler.cmdproc.complete(leading, last_token) end if 1 == completion.size completion_token = completion[0] if last_token.end_with?(' ') if last_token.rstrip == completion_token # There is nothing more to complete [] else [] end else [completion_token] end else # We have multiple completions. Get the last token so that will # be presented as a list of completions. completion end end
# File lib/trepanning.rb, line 248 def process_cmdfile_setting(settings) p settings puts caller exit settings[:cmdfiles].each do |item| cmdfile, opts = if item.kind_of?(Array) item else [item, {}] end add_command_file(cmdfile, opts) end if settings.member?(:cmdfiles) end
Trepan.start(options)
-> bool Trepan.start(options)
{ … } -> obj
If it’s called without a block it returns true
, unless debugger was already started. If a block is given, it starts debugger and yields to block. When the block is finished executing it stops the debugger with Trepan.stop method.
If a block is given, it starts debugger and yields to block. When the block is finished executing it stops the debugger with Trepan.stop method. Inside the block you will probably want to have a call to Trepan.debugger. For example:
Trepan.start{debugger; foo} # Stop inside of foo
Also, ruby-debug only allows one invocation of debugger at a time; nested Trepan.start
‘s have no effect and you can’t use this inside the debugger itself.
Note that if you want to stop debugger, you must call Trepan.stop as many time as you called Trepan.start method.
options
is a hash used to set various debugging options. Set :init true if you want to save ARGV and some variables which make a debugger restart possible. Only the first time :init is set true will values get set. Since ARGV is saved, you should make sure it hasn’t been changed before the (first) call. Set :post_mortem true if you want to enter post-mortem debugging on an uncaught exception. Once post-mortem debugging is set, it can’t be unset.
# File lib/trepanning.rb, line 114 def start(options={}, &block) options = Trepan::DEFAULT_START_SETTINGS.merge(options) if options[:init] Trepan.const_set('ARGV', ARGV.clone) unless defined? Trepan::ARGV Trepan.const_set('PROG_SCRIPT', $0) unless defined? Trepan::PROG_SCRIPT Trepan.const_set('INITIAL_DIR', Dir.pwd) unless defined? Trepan::INITIAL_DIR end Trepan.tracing = options[:tracing] unless options[:tracing].nil? retval = Debugger.started? ? block && block.call(self) : Debugger.start_(&block) if options[:post_mortem] post_mortem end return retval end
Connects to the remote debugger
# File lib/trepanning.rb, line 198 def start_client(host = 'localhost', port = PORT) require "socket" interface = Trepan::LocalInterface.new socket = TCPSocket.new(host, port) puts "Connected." catch(:exit) do while (line = socket.gets) case line when /^PROMPT (.*)$/ input = interface.read_command($1) throw :exit unless input socket.puts input when /^CONFIRM (.*)$/ input = interface.confirm($1) throw :exit unless input socket.puts input else print line end end end socket.close end
Starts a remote debugger.
# File lib/trepanning.rb, line 139 def start_remote(host = nil, port = PORT, post_mortem = false) return if @thread return if started? self.interface = nil start self.post_mortem if post_mortem if port.kind_of?(Array) cmd_port, ctrl_port = port else cmd_port, ctrl_port = port, port + 1 end ctrl_port = start_control(host, ctrl_port) yield if block_given? mutex = Mutex.new proceed = ConditionVariable.new server = TCPServer.new(host, cmd_port) @cmd_port = cmd_port = server.addr[1] @thread = Debugger::DebugThread.new do while (session = server.accept) self.interface = RemoteInterface.new(session) if wait_connection mutex.synchronize do proceed.signal end end end end if wait_connection mutex.synchronize do proceed.wait(mutex) end end end
# File lib/trepanning.rb, line 132 def started? Debugger.started? end