-
Notifications
You must be signed in to change notification settings - Fork 82
Open
Description
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:
- Ubuntu 18.04
- Docker Linux 19.03.7
- Mac 10.15 Catalina
- Docker Mac 2.2.0.3
- Ruby 1.9.3
- Rails 3.2
- RubyMine 2019.3
- ruby-debug-base19x 0.11.32
- ruby-debug-ide 0.7-beta7 with port fix
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.
AChesaronewheelq
Metadata
Metadata
Assignees
Labels
No labels