Module: Debugger::MultiProcess

Defined in:
lib/ruby-debug-ide/multiprocess/monkey.rb,
lib/ruby-debug-ide/multiprocess/pre_child.rb

Class Method Summary collapse

Class Method Details

.create_mp_execObject



18
19
20
21
22
23
24
25
26
27
# File 'lib/ruby-debug-ide/multiprocess/monkey.rb', line 18

def self.create_mp_exec
  %Q{
    alias pre_debugger_exec exec

    def exec(*args)
      Debugger.interface.close
      pre_debugger_exec(*args)
    end
  }
end

.create_mp_forkObject



3
4
5
6
7
8
9
10
11
12
13
14
15
16
# File 'lib/ruby-debug-ide/multiprocess/monkey.rb', line 3

def self.create_mp_fork
  %Q{
    alias pre_debugger_fork fork

    def fork(*args)
      if block_given?
        return pre_debugger_fork{Debugger::MultiProcess::pre_child; yield}
      end
      result = pre_debugger_fork
      Debugger::MultiProcess::pre_child unless result
      result
    end
  }
end

.find_free_port(host) ⇒ Object



64
65
66
67
68
69
# File 'lib/ruby-debug-ide/multiprocess/pre_child.rb', line 64

def find_free_port(host)
  server = TCPServer.open(host, 0)
  port   = server.addr[1]
  server.close
  port
end

.pre_childObject



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/ruby-debug-ide/multiprocess/pre_child.rb', line 4

def pre_child

  require "socket"
  require "ostruct"

  host = ENV['DEBUGGER_HOST']
  port = find_free_port(host)

  options = OpenStruct.new(
      'frame_bind'  => false,
      'host'        => host,
      'load_mode'   => false,
      'port'        => port,
      'stop'        => false,
      'tracing'     => false,
      'int_handler' => true
  )

  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
      s = TCPSocket.open(acceptor_host, acceptor_port)
      s.print(port)
      s.close
      connected = true
      start_debugger(options)
      return
    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
end

.start_debugger(options) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/ruby-debug-ide/multiprocess/pre_child.rb', line 43

def start_debugger(options)
  if Debugger.started?
    #we're in forked child, only need to restart control thread
    Debugger.breakpoints.clear
    Debugger.control_thread = nil
    Debugger.start_control(options.host, options.port)
  end

  if options.int_handler
    # install interruption handler
    trap('INT') { Debugger.interrupt_last }
  end

  # set options
  Debugger.keep_frame_binding = options.frame_bind
  Debugger.tracing = options.tracing

  Debugger.prepare_debugger(options)
end