Debugger

Constants

DEFAULT_START_SETTINGS

Default options to Debugger.start

HOME_DIR
INITFILE

Of course MS Windows has to be different

PORT

the port number used for remote debugging

RUBY_DEBUG_DIR
VERSION

Attributes

annotate[RW]

gdb-style annotation mode. Used in GNU Emacs interface

cmd_port[R]
control_thread[R]
ctrl_port[R]
handler[RW]

interface modules provide handler object

last_exception[RW]
printer[RW]
reload_source_on_change[RW]

if true, checks the modification time of source files and reloads if it was modified

start_sentinal[RW]

If set, a string to look for in caller() and is used to see if the call stack is truncated.

thread[R]
wait_connection[RW]

in remote mode, wait for the remote connection

Public Class Methods

handle_post_mortem(exp) click to toggle source
# File lib/ruby-debug-base.rb, line 150
def handle_post_mortem(exp)
  return if !exp || !exp.__debug_context ||
    exp.__debug_context.stack_size == 0
  Debugger.suspend
  orig_tracing = Debugger.tracing, Debugger.current_context.tracing
  Debugger.tracing = Debugger.current_context.tracing = false
  Debugger.last_exception = exp
  handler.at_line(exp.__debug_context, exp.__debug_file, exp.__debug_line)
ensure
  Debugger.tracing, Debugger.current_context.tracing = orig_tracing
  Debugger.resume
end
interrupt() click to toggle source

Interrupts the current thread

# File lib/ruby-debug-base.rb, line 78
def interrupt
  current_context.interrupt
end
interrupt_last() click to toggle source

Interrupts the last debugged thread

# File lib/ruby-debug-base.rb, line 85
def interrupt_last
  if context = last_context
    return nil unless context.thread.alive?
    context.interrupt
  end
  context
end
post_mortem() click to toggle source

Activates the post-mortem mode. There are two ways of using it:

Global post-mortem mode

By calling Debugger.post_mortem method without a block, you install at_exit hook that intercepts any unhandled by your script exceptions and enables post-mortem mode.

Local post-mortem mode

If you know that a particular block of code raises an exception you can enable post-mortem mode by wrapping this block with Debugger.post_mortem, e.g.

def offender
   raise 'error'
end
Debugger.post_mortem do
   ...
   offender
   ...
end
# File lib/ruby-debug-base.rb, line 129
def post_mortem
  if block_given?
    old_post_mortem = self.post_mortem?
    begin
      self.post_mortem = true
      yield
    rescue Exception => exp
      handle_post_mortem(exp)
      raise
    ensure
      self.post_mortem = old_post_mortem
    end
  else
    return if post_mortem?
    self.post_mortem = true
    debug_at_exit do
      handle_post_mortem($!) if $! && post_mortem?
    end
  end
end
run_init_script(out = handler.interface) click to toggle source

Runs normal debugger initialization scripts Reads and executes the commands from init file (if any) in the current working directory. This is only done if the current directory is different from your home directory. Thus, you can have more than one init file, one generic in your home directory,

and another, specific to the program you are debugging, in the

directory where you invoke ruby-debug.

# File lib/ruby-debug.rb, line 137
def run_init_script(out = handler.interface)
  cwd_script_file  = File.expand_path(File.join(".", INITFILE))
  run_script(cwd_script_file, out) if File.exists?(cwd_script_file)

  home_script_file = File.expand_path(File.join(HOME_DIR, INITFILE))
  run_script(home_script_file, out) if File.exists?(home_script_file) and
    cwd_script_file != home_script_file
end
run_script(file, out = handler.interface, verbose=false) click to toggle source

Runs a script file

# File lib/ruby-debug.rb, line 149
def run_script(file, out = handler.interface, verbose=false)
  interface = ScriptInterface.new(File.expand_path(file), out)
  processor = ControlCommandProcessor.new(interface)
  processor.process_commands(verbose)
end
settings() click to toggle source

Returns setting object. Use Debugger.settings[] and Debugger.settings[]= methods to query and set debugger settings. These settings are available:

  • :autolist - automatically calls ‘list’ command on breakpoint

  • :autoeval - evaluates input in the current binding if it’s not recognized as a debugger command

  • :autoirb - automatically calls ‘irb’ command on breakpoint

  • :stack_trace_on_error - shows full stack trace if eval command results with an exception

  • :frame_full_path - displays full paths when showing frame stack

  • :frame_class_names - displays method’s class name when showing frame stack

  • :reload_source_on_change - makes ‘list’ command to always display up-to-date source code

  • :force_stepping - stepping command asways move to the new line

# File lib/ruby-debug/command.rb, line 236
def self.settings
  Command.settings
end
source_reload() click to toggle source
# File lib/ruby-debug-base.rb, line 93
def source_reload
  Object.send(:remove_const, "SCRIPT_LINES__") if Object.const_defined?("SCRIPT_LINES__")
  Object.const_set("SCRIPT_LINES__", {})
  LineCache::clear_file_cache
end
start(options={}, &block) click to toggle source

Debugger.start(options) -> bool Debugger.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 Debugger.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 Debugger.stop method. Inside the block you will probably want to have a call to Debugger.debugger. For example:

Debugger.start{debugger; foo}  # Stop inside of foo

Also, ruby-debug only allows one invocation of debugger at a time; nested Debugger.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 Debugger.stop as many time as you called Debugger.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/ruby-debug-base.rb, line 202
def start(options={}, &block)
  options = Debugger::DEFAULT_START_SETTINGS.merge(options)
  if options[:init]
    Debugger.const_set('ARGV', ARGV.clone) unless
      defined? Debugger::ARGV
    Debugger.const_set('PROG_SCRIPT', $0) unless
      defined? Debugger::PROG_SCRIPT
    Debugger.const_set('INITIAL_DIR', Dir.pwd) unless
      defined? Debugger::INITIAL_DIR
  end
  Debugger.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
start_client(host = 'localhost', port = PORT) click to toggle source

Connects to the remote debugger

# File lib/ruby-debug.rb, line 105
def start_client(host = 'localhost', port = PORT)
  require "socket"
  interface = Debugger::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
start_remote(host = nil, port = PORT) click to toggle source

Starts a remote debugger.

# File lib/ruby-debug.rb, line 49
def start_remote(host = nil, port = PORT)
  return if @thread

  self.interface = nil
  start

  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 = 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
Also aliased as: start_server
start_server(host = nil, port = PORT) click to toggle source
Alias for: start_remote

[Validate]

Generated with the Darkfish Rdoc Generator 2.