module Byebug
def self.attach(steps_out, before)
events occur. Before entering byebug the init script is read.
Enters byebug right before (or right after if _before_ is false) return
def self.attach(steps_out, before) start self.debugged_program = $PROGRAM_NAME run_init_script(StringIO.new) current_context.step_out(steps_out, before) end
def self.handle_post_mortem
prompt back to the user before program termination.
Saves information about the unhandled exception and gives a byebug
def self.handle_post_mortem context = Byebug.raised_exception.__bb_context file = Byebug.raised_exception.__bb_file line = Byebug.raised_exception.__bb_line Byebug.handler.at_line(context, file, line) end
def self.interface=(value)
Byebug's interface is its handler's interface
def self.interface=(value) handler.interface = value end
def self.run_init_script(out = handler.interface)
program you are debugging, in the directory where you invoke byebug.
file, one generic in your home directory, and another, specific to the
different from your home directory. Thus, you can have more than one init
working directory. This is only done if the current directory is
Reads and executes the commands from init file (if any) in the current
Runs normal byebug initialization scripts.
def self.run_init_script(out = handler.interface) cwd_script = File.expand_path(File.join('.', INIT_FILE)) run_script(cwd_script, out, true) if File.exist?(cwd_script) home_script = File.expand_path(File.join(ENV['HOME'].to_s, INIT_FILE)) if File.exist?(home_script) && cwd_script != home_script run_script(home_script, out, true) end end
def self.run_script(file, out = handler.interface, verbose = false)
Runs a script file
def self.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
def self.source_reload
def self.source_reload hsh = 'SCRIPT_LINES__' Object.send(:remove_const, hsh) if Object.const_defined?(hsh) Object.const_set(hsh, {}) end
def interrupt
Interrupts the current thread
def interrupt current_context.interrupt end
def start_client(host = 'localhost', port = PORT)
Connects to the remote byebug
def start_client(host = 'localhost', port = PORT) interface = LocalInterface.new socket = TCPSocket.new(host, port) puts 'Connected.' catch(:exit) do while (line = socket.gets) case line when /^PROMPT (.*)$/ input = interface.read_command(Regexp.last_match[1]) throw :exit unless input socket.puts input when /^CONFIRM (.*)$/ input = interface.confirm(Regexp.last_match[1]) throw :exit unless input socket.puts input else puts line end end end socket.close end
def start_control(host = nil, ctrl_port = PORT + 1)
def start_control(host = nil, ctrl_port = PORT + 1) return @actual_control_port if @control_thread server = TCPServer.new(host, ctrl_port) @actual_control_port = server.addr[1] @control_thread = DebugThread.new do while (session = server.accept) interface = RemoteInterface.new(session) ControlCommandProcessor.new(interface).process_commands end end @actual_control_port end
def start_server(host = nil, port = PORT)
Starts a remote byebug
def start_server(host = nil, port = PORT) return if @thread self.interface = nil start start_control(host, port == 0 ? 0 : port + 1) yield if block_given? mutex = Mutex.new proceed = ConditionVariable.new server = TCPServer.new(host, port) self.actual_port = server.addr[1] @thread = DebugThread.new do while (session = server.accept) self.interface = RemoteInterface.new(session) mutex.synchronize { proceed.signal } if wait_connection end end mutex.synchronize { proceed.wait(mutex) } if wait_connection end