ruby-debug / ruby-debug-ide

An interface which glues ruby-debug to IDEs like Eclipse (RDT), NetBeans and RubyMine.
https://www.jetbrains.com/ruby/features/ruby_debugger.html
Other
370 stars 83 forks source link

Error Raised when Debugging a Multi-Process app in Docker on a Mac #186

Open mrbiggred opened 4 years ago

mrbiggred commented 4 years ago

I fixed the issue of debugging a multi-process app in Docker by using @ViugiNick PR. His fix works on Linux but I ran into another issue when trying to debug on a Mac:

Attaching to web_1
web_1       | Evaluation memory limit is ineffective in JRuby and MRI < 2.0
web_1       | Fast Debugger (ruby-debug-ide 0.7.0.beta7, ruby-debug-base19x 0.11.32, file filtering is not supported) listens on 0.0.0.0:1234
web_1       | true
=> Booting Unicorn
web_1       | => Rails 3.2.22.5 application starting in development on http://0.0.0.0:3000
web_1       | => Call with -d to detach
web_1       | => Ctrl-C to shutdown server
web_1       | listening on addr=0.0.0.0:8080 fd=13
web_1       | master process ready
web_1       | 28: go create dispatcher socket 172.23.0.1 26168
web_1       | 28: connection failed(1)
web_1       | Exception: Connection refused - connect(2)
web_1       |   /app/config/initializers/ruby_debug_ide.rb:43:in `initialize'
web_1       |   /app/config/initializers/ruby_debug_ide.rb:43:in `open'
web_1       |   /app/config/initializers/ruby_debug_ide.rb:43:in `block in notify_dispatcher_if_needed'
web_1       |   /app/config/initializers/ruby_debug_ide.rb:36:in `times'
web_1       |   /app/config/initializers/ruby_debug_ide.rb:36:in `notify_dispatcher_if_needed'
web_1       |   /usr/local/bundle/bundler/gems/ruby-debug-ide-3099814624fa/lib/ruby-debug-ide.rb:120:in `block in start_control'
web_1       | 28: go create dispatcher socket 172.23.0.1 26168
web_1       | 28: connection failed(2)

I figured out the problem is when the Debugger tries to contact the host in the notify_dispatcher_if_needed method. It uses the internal Docker IP address (e.g. 172.23.0.1) which works fine on Linux but not Mac. On Mac you need to use host.docker.internal as outlined here.

As a workaround for now I created the following monkey patch in my application:

# config/initializers/ruby_debug_ide.rb

# In non-dev and rake tasks the Ruby Debug IDE gem
# is not loaded so there is nothing to override.
if defined?(Debugger)
  Debugger.module_eval do
    class << self
      def notify_dispatcher_if_needed(host, port, need_notify)
        return yield port unless need_notify

        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
        connected = false

        3.times do |i|
          begin
            $stderr.puts "#{Process.pid}: go create dispatcher socket #{acceptor_host} #{acceptor_port}"

            # Try to connect using the host IP address.  If that fails
            # then assume we are on a Mac and try the internal DNS.
            begin
              s = TCPSocket.open(acceptor_host, acceptor_port)
            rescue
              # Assume we are on a Mac and try the internal host DNS.
              s = TCPSocket.open('host.docker.internal', acceptor_port)
            end

            dispatcher_answer = s.gets.chomp

            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 server
          rescue => bt
            $stderr.puts "#{Process.pid}: connection failed(#{i + 1})"
            $stderr.puts "Exception: #{bt}"
            $stderr.puts bt.backtrace.map { |l| "\t#{l}" }.join("\n")
            sleep 0.3
          end unless connected
        end

        nil
      end
    end
  end
end

My specs:

gem 'ruby-debug-ide', git: 'https://github.com/ViugiNick/ruby-debug-ide.git', branch: 'so_reuseport'
gem 'ruby-debug-base19x'

Feedback for a better way to fix this issue would be much appreciated. My plan is to try the fix for a couple weeks and if it appears to work maybe create PR, time permitting.

nomasprime commented 2 years ago

Trying out RubyMine and ran into this.

Still no solution after two years?

mrbiggred commented 1 year ago

Just a heads up that I created a fork of ruby-debug-ide that fixes the DNS when using Docker Desktop. Please try it out and let me know if it works for you. If you haven any questions, spot an issue, or have an improvement please let me know by opening a issue or PR in the forked repo.