diff --git a/bin/rdebug-ide b/bin/rdebug-ide index a72dfd1..698564e 100755 --- a/bin/rdebug-ide +++ b/bin/rdebug-ide @@ -131,6 +131,14 @@ else Debugger::PROG_SCRIPT = $0 end +if RUBY_VERSION < "1.9" + lib_path = File.expand_path(File.dirname(__FILE__) + "/../lib/") + $: << lib_path unless $:.include? lib_path + require 'ruby-debug-ide/thread_alias.rb' +else + require_relative '../lib/ruby-debug-ide/thread_alias' +end + if options.dispatcher_port != -1 ENV['IDE_PROCESS_DISPATCHER'] = options.dispatcher_port.to_s if RUBY_VERSION < "1.9" diff --git a/lib/ruby-debug-ide.rb b/lib/ruby-debug-ide.rb index 62c0671..7874134 100644 --- a/lib/ruby-debug-ide.rb +++ b/lib/ruby-debug-ide.rb @@ -18,6 +18,13 @@ module Debugger class << self + def find_free_port(host) + server = TCPServer.open(host, 0) + port = server.addr[1] + server.close + port + end + # Prints to the stderr using printf(*args) if debug logging flag (-d) is on. def print_debug(*args) if Debugger.cli_debug @@ -111,9 +118,15 @@ def start_control(host, port, notify_dispatcher) # 127.0.0.1 seemingly works with all systems and with IPv6 as well. # "localhost" and nil have problems on some systems. host ||= '127.0.0.1' - server = TCPServer.new(host, port) - print_greeting_msg($stderr, host, port) if defined? IDE_VERSION - notify_dispatcher(port) if notify_dispatcher + + server = notify_dispatcher_if_needed(host, port, notify_dispatcher) do |real_port, port_changed = false| + s = TCPServer.new(host, real_port) + print_greeting_msg $stderr, host, real_port, port_changed ? "Subprocess" : "Fast" if defined? IDE_VERSION + s + end + + return unless server + while (session = server.accept) $stderr.puts "Connected from #{session.peeraddr[2]}" if Debugger.cli_debug dispatcher = ENV['IDE_PROCESS_DISPATCHER'] @@ -141,8 +154,9 @@ def start_control(host, port, notify_dispatcher) private + def notify_dispatcher_if_needed(host, port, need_notify) + return yield port unless need_notify - def notify_dispatcher(port) return unless ENV['IDE_PROCESS_DISPATCHER'] acceptor_host, acceptor_port = ENV['IDE_PROCESS_DISPATCHER'].split(":") acceptor_host, acceptor_port = '127.0.0.1', acceptor_host unless acceptor_port @@ -151,11 +165,19 @@ def notify_dispatcher(port) 3.times do |i| begin s = TCPSocket.open(acceptor_host, acceptor_port) + dispatcher_answer = s.gets.chomp + + if dispatcher_answer == "true" + port = Debugger.find_free_port(host) + end + + server = yield port, dispatcher_answer == "true" + s.print(port) s.close connected = true print_debug "Ide process dispatcher notified about sub-debugger which listens on #{port}\n" - return + return server rescue => bt $stderr.puts "#{Process.pid}: connection failed(#{i+1})" $stderr.puts "Exception: #{bt}" @@ -164,7 +186,6 @@ def notify_dispatcher(port) end unless connected end end - end class Exception # :nodoc: diff --git a/lib/ruby-debug-ide/command.rb b/lib/ruby-debug-ide/command.rb index e6ee3e1..55f96f7 100644 --- a/lib/ruby-debug-ide/command.rb +++ b/lib/ruby-debug-ide/command.rb @@ -128,9 +128,18 @@ def debug_eval(str, b = get_binding) to_inspect = Command.unescape_incoming(str) max_time = Debugger.evaluation_timeout @printer.print_debug("Evaluating %s with timeout after %i sec", str, max_time) + + Debugger::TimeoutHandler.do_thread_alias + + eval_result = nil + timeout(max_time) do - eval(to_inspect, b) + eval_result = eval(to_inspect, b) end + + Debugger::TimeoutHandler.undo_thread_alias + + return eval_result rescue StandardError, ScriptError => e @printer.print_exception(e, @state.binding) throw :debug_error diff --git a/lib/ruby-debug-ide/greeter.rb b/lib/ruby-debug-ide/greeter.rb index df9b042..7e3dd93 100644 --- a/lib/ruby-debug-ide/greeter.rb +++ b/lib/ruby-debug-ide/greeter.rb @@ -10,7 +10,7 @@ module Debugger class << self - def print_greeting_msg(stream, host, port) + def print_greeting_msg(stream, host, port, debugger_name = "Fast") base_gem_name = if defined?(JRUBY_VERSION) || RUBY_VERSION < '1.9.0' 'ruby-debug-base' elsif RUBY_VERSION < '2.0.0' @@ -31,7 +31,7 @@ def print_greeting_msg(stream, host, port) listens_on = "\n" end - msg = "Fast Debugger (ruby-debug-ide #{IDE_VERSION}, #{base_gem_name} #{VERSION}, file filtering is #{file_filtering_support})" + listens_on + msg = "#{debugger_name} Debugger (ruby-debug-ide #{IDE_VERSION}, #{base_gem_name} #{VERSION}, file filtering is #{file_filtering_support})" + listens_on stream.printf msg end diff --git a/lib/ruby-debug-ide/multiprocess/pre_child.rb b/lib/ruby-debug-ide/multiprocess/pre_child.rb index 4a349fd..b707fc4 100644 --- a/lib/ruby-debug-ide/multiprocess/pre_child.rb +++ b/lib/ruby-debug-ide/multiprocess/pre_child.rb @@ -11,7 +11,7 @@ def pre_child(options = nil) 'frame_bind' => false, 'host' => host, 'load_mode' => false, - 'port' => find_free_port(host), + 'port' => Debugger.find_free_port(host), 'stop' => false, 'tracing' => false, 'int_handler' => true, @@ -24,7 +24,7 @@ def pre_child(options = nil) ) if(options.ignore_port) - options.port = find_free_port(options.host) + options.port = Debugger.find_free_port(options.host) options.notify_dispatcher = true end @@ -54,14 +54,6 @@ def start_debugger(options) Debugger.cli_debug = options.cli_debug Debugger.prepare_debugger(options) end - - - def find_free_port(host) - server = TCPServer.open(host, 0) - port = server.addr[1] - server.close - port - end end end end \ No newline at end of file diff --git a/lib/ruby-debug-ide/thread-alias/alias_thread.rb b/lib/ruby-debug-ide/thread-alias/alias_thread.rb new file mode 100644 index 0000000..a37eddb --- /dev/null +++ b/lib/ruby-debug-ide/thread-alias/alias_thread.rb @@ -0,0 +1,2 @@ +OldThread = Thread +Thread = Debugger::DebugThread \ No newline at end of file diff --git a/lib/ruby-debug-ide/thread-alias/unalias_thread.rb b/lib/ruby-debug-ide/thread-alias/unalias_thread.rb new file mode 100644 index 0000000..8ead867 --- /dev/null +++ b/lib/ruby-debug-ide/thread-alias/unalias_thread.rb @@ -0,0 +1 @@ +Thread = OldThread \ No newline at end of file diff --git a/lib/ruby-debug-ide/thread_alias.rb b/lib/ruby-debug-ide/thread_alias.rb new file mode 100644 index 0000000..1cc38d4 --- /dev/null +++ b/lib/ruby-debug-ide/thread_alias.rb @@ -0,0 +1,13 @@ +module Debugger + module TimeoutHandler + class << self + def do_thread_alias + load File.expand_path(File.dirname(__FILE__) + '/thread-alias/alias_thread.rb') + end + + def undo_thread_alias + load File.expand_path(File.dirname(__FILE__) + '/thread-alias/unalias_thread.rb') + end + end + end +end \ No newline at end of file diff --git a/lib/ruby-debug-ide/version.rb b/lib/ruby-debug-ide/version.rb index 41f8b9f..d14c8d8 100755 --- a/lib/ruby-debug-ide/version.rb +++ b/lib/ruby-debug-ide/version.rb @@ -1,3 +1,3 @@ module Debugger - IDE_VERSION='0.6.1' + IDE_VERSION='0.7.0.beta2' end