debugger-xml 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OTZiODljZjRmYmUxMzk5NTEwMTMwNzlhMWM4NWY3MjhmMGQxOTk3Mw==
4
+ Y2MzNzI1ODA4M2M0MWU1NDFjNGJiZWU4MzMxZWI1N2NiMDczNWQzNg==
5
5
  data.tar.gz: !binary |-
6
- OTM4ZDY2YzJhYzJmMDZkOGU0ZDY4MjA3MDBkZjhmYjE4NWFhZDYxOA==
6
+ NmQ5ZmRkMmEwYTE5NGZjMzdhOWQ2MzVmMTE1ZmI0ZDFjOGQyNjNjYg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- ZTFlNGRkNTdlMzlmMDQyNWEyMDgyYzk4YzJiZTVhYjA3YTU2NDlmMTY3YmJj
10
- Mzk4YTFkNDdlNDA1ZjI0Mzk5M2Q5ZmYxOTNjY2EzNjk2NzQyMDNkMmQzNmJl
11
- YWVhNzlmMjMxN2FiMTdiMjUwZGExNDUwZmMwMzRiOTdjZDk3OTY=
9
+ NzYwOTdlOTIwOGEzZjYwMmExYWJhMWE0YzkxNDA3MzYxYWNmODVkNjVhMmI1
10
+ ZjAyNzJjOTZlMzc2NzViN2M0YTExMDcwMzk5N2RkYTI5Yzk3YzE3YmNkYTQ1
11
+ YmFkMjJjNGNmMzVmZDJiMmI0MTczMTMyNzkxODUyZWEwYjFlYWU=
12
12
  data.tar.gz: !binary |-
13
- YzhjZDIwZmU1YzA3ZGY1MWVlN2MxYjBmZmZiM2M0YWQ0N2JlNmMxNmFmM2I2
14
- MjcwNDc1MzViOTM2MmZlMTBkODQ1YzQ5ZTFmMGVmNmNlOWRjMDQ1Nzc2OTNm
15
- YTgzYzU5ZjMwNWZlYjgwMzE0MWZjZjNhMmM3YTQ1ZjJlMDAzY2E=
13
+ YmUwNDcwYmFjZDc4ZmM0OGI0NmUxYWY0YWIyZmZkNDQ2MzYwNzFjNmNlZjAy
14
+ YTdhNjFjZjM3NmQ3ZmFhYWJmYmFmZjUyNDlmODNmZjNmZmY0MDZhYzNjODYz
15
+ ZjZjODg1NzBjZWIwMzU1M2NjNDkxOWYzYTMxYzI4NTg2MGI4MDQ=
data/bin/rdebug-ide CHANGED
@@ -14,7 +14,7 @@ class RdebugIde
14
14
  check_argv!
15
15
  Debugger.const_set("ARGV", ARGV.clone)
16
16
  Debugger.const_set("RDEBUG_SCRIPT", rdebug_path)
17
- install_interruption_hander if options.int_handler
17
+ install_interruption_handler if options.int_handler
18
18
  Debugger.tracing = options.tracing
19
19
  Debugger.wait_for_start = options.wait_for_start
20
20
  Debugger.wait_connection = true
@@ -25,6 +25,7 @@ class RdebugIde
25
25
  else
26
26
  Debugger::Xml::FakeLogger.new
27
27
  end
28
+ init_multi_process_debug(options) if options.dispatcher_port
28
29
  end
29
30
 
30
31
  def run
@@ -38,7 +39,17 @@ class RdebugIde
38
39
 
39
40
  private
40
41
 
41
- def check_argv!
42
+ def init_multi_process_debug(options)
43
+ ENV['IDE_PROCESS_DISPATCHER'] = options.dispatcher_port.to_s
44
+ ENV['DEBUGGER_HOST'] = options.host.to_s
45
+ ENV['DEBUGGER_DEBUG_MODE'] = options.debug_mode.to_s
46
+ ENV['DEBUGGER_STORED_RUBYLIB'] = $LOAD_PATH.join(File::PATH_SEPARATOR)
47
+ old_opts = ENV['RUBYOPT']
48
+ ENV['RUBYOPT'] = "-r#{File.expand_path(File.dirname(__FILE__))}/../lib/debugger/xml/multiprocess/starter"
49
+ ENV['RUBYOPT'] += " #{old_opts}" if old_opts
50
+ end
51
+
52
+ def check_argv!
42
53
  if ARGV.empty?
43
54
  puts opts
44
55
  puts
@@ -47,7 +58,7 @@ class RdebugIde
47
58
  end
48
59
  end
49
60
 
50
- def install_interruption_hander
61
+ def install_interruption_handler
51
62
  trap('INT') { Debugger.interrupt_last }
52
63
  end
53
64
 
@@ -68,7 +79,7 @@ class RdebugIde
68
79
  @opts ||= begin
69
80
  @options = OpenStruct.new(
70
81
  host: "127.0.0.1", port: 12345, stop: false, tracing: false, wait_for_start: true,
71
- int_handler: true, debug_mode: false
82
+ int_handler: true, debug_mode: false, dispatcher_port: nil
72
83
  )
73
84
  opts = OptionParser.new do |opts|
74
85
  opts.banner = %{
@@ -79,9 +90,11 @@ class RdebugIde
79
90
  opts.separator ""
80
91
  opts.separator "Options:"
81
92
  opts.on("-h", "--host HOST", "Host name used for remote debugging") { |host| @options.host = host }
82
- opts.on("-d", "--debug", "Enable debug mode") { |host| @options.debug_mode = true }
83
- opts.on("--cport PORT", Integer, "Port used for control commands") { |cport| @options.cport = cport }
84
93
  opts.on("-p", "--port PORT", Integer, "Port used for remote debugging") { |port| @options.port = port }
94
+ opts.on('--dispatcher-port PORT', Integer, 'Port used for multi-process debugging dispatcher') do |dp|
95
+ @options.dispatcher_port = dp
96
+ end
97
+ opts.on("-d", "--debug", "Enable debug mode") { |host| @options.debug_mode = true }
85
98
  opts.on("--wait", String, "Wait for 'start' command") do |bool|
86
99
  @options.wait_for_start = (bool == "false" ? false : true)
87
100
  end
@@ -108,6 +108,7 @@ thread:
108
108
  id: "{id}"
109
109
  status: "{status}"
110
110
  current: "{current}"
111
+ pid: "{pid}"
111
112
 
112
113
  variable:
113
114
  variable:
@@ -3,7 +3,9 @@ module Debugger
3
3
 
4
4
  # Mark should be 'true' or 'false', as a String
5
5
  def get_pr_arguments_with_xml(mark, *args)
6
- get_pr_arguments_without_xml((!!mark).to_s, *args)
6
+ res = get_pr_arguments_without_xml((!!mark).to_s, *args)
7
+ res[:file] = File.expand_path(res[:file])
8
+ res
7
9
  end
8
10
 
9
11
  alias_method :get_pr_arguments_without_xml, :get_pr_arguments
@@ -0,0 +1,10 @@
1
+ module Debugger
2
+ module ThreadFunctions # :nodoc:
3
+ def thread_arguments_with_pid(context, should_show_top_frame = true)
4
+ thread_arguments_without_pid(context, should_show_top_frame).merge(pid: Process.pid)
5
+ end
6
+
7
+ alias_method :thread_arguments_without_pid, :thread_arguments
8
+ alias_method :thread_arguments, :thread_arguments_with_pid
9
+ end
10
+ end
@@ -1,4 +1,11 @@
1
1
  module Debugger
2
+ module VarFunctions # :nodoc:
3
+
4
+ def var_global
5
+ var_list(global_variables.reject { |v| [:$=, :$KCODE, :$-K, :$FILENAME].include?(v) })
6
+ end
7
+
8
+ end
2
9
  class VarInstanceCommand < Command
3
10
 
4
11
  def execute_with_xml(*args)
@@ -1,6 +1,6 @@
1
1
  module Debugger
2
2
  class << self
3
- attr_accessor :wait_for_start
3
+ attr_accessor :wait_for_start, :control_thread
4
4
 
5
5
  def start_remote_ide(host, port)
6
6
  return if @control_thread
@@ -11,6 +11,10 @@ module Debugger
11
11
  $stderr.printf "Fast Debugger (debugger-xml #{Xml::VERSION}) listens on #{host}:#{port}\n"
12
12
  server = TCPServer.new(host, port)
13
13
  while (session = server.accept)
14
+ dispatcher = ENV['IDE_PROCESS_DISPATCHER']
15
+ if dispatcher && !dispatcher.include?(":")
16
+ ENV['IDE_PROCESS_DISPATCHER'] = "#{session.peeraddr[2]}:#{dispatcher}"
17
+ end
14
18
  interface = Xml::Ide::Interface.new(session)
15
19
  processor = Xml::Ide::ControlCommandProcessor.new(interface)
16
20
  self.handler = Xml::Ide::Processor.new(interface)
@@ -0,0 +1,49 @@
1
+ module Debugger
2
+ module Xml
3
+ module MultiProcess
4
+ def self.create_mp_fork(private=false)
5
+ %Q{
6
+ alias pre_debugger_fork fork
7
+
8
+ #{private ? "private" : ""}
9
+ def fork(*args)
10
+ if block_given?
11
+ return pre_debugger_fork{Debugger::Xml::MultiProcess::pre_child; yield}
12
+ end
13
+ result = pre_debugger_fork
14
+ Debugger::Xml::MultiProcess::pre_child unless result
15
+ result
16
+ end
17
+ }
18
+ end
19
+
20
+ def self.create_mp_exec(private=false)
21
+ %Q{
22
+ alias pre_debugger_exec exec
23
+
24
+ #{private ? "private" : ""}
25
+ def exec(*args)
26
+ Debugger.handler.interface.close
27
+ pre_debugger_exec(*args)
28
+ end
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ module Kernel
36
+ class << self
37
+ module_eval Debugger::Xml::MultiProcess.create_mp_fork
38
+ module_eval Debugger::Xml::MultiProcess.create_mp_exec
39
+ end
40
+ module_eval Debugger::Xml::MultiProcess.create_mp_fork(true)
41
+ module_eval Debugger::Xml::MultiProcess.create_mp_exec(true)
42
+ end
43
+
44
+ module Process
45
+ class << self
46
+ module_eval Debugger::Xml::MultiProcess.create_mp_fork
47
+ module_eval Debugger::Xml::MultiProcess.create_mp_exec
48
+ end
49
+ end
@@ -0,0 +1,80 @@
1
+ module Debugger
2
+ module Xml
3
+ module MultiProcess
4
+ class << self
5
+ def pre_child
6
+
7
+ require 'socket'
8
+ require 'ostruct'
9
+
10
+ host = ENV['DEBUGGER_HOST']
11
+ port = find_free_port(host)
12
+
13
+ options = OpenStruct.new(
14
+ host: host,
15
+ port: port,
16
+ stop: false,
17
+ tracing: false,
18
+ wait_for_start: true,
19
+ int_handler: true,
20
+ debug_mode: (ENV['DEBUGGER_DEBUG_MODE'] == 'true'),
21
+ dispatcher_port: ENV['IDE_PROCESS_DISPATCHER']
22
+ )
23
+
24
+ acceptor_host, acceptor_port = ENV['IDE_PROCESS_DISPATCHER'].split(":")
25
+ acceptor_host, acceptor_port = '127.0.0.1', acceptor_host unless acceptor_port
26
+
27
+ connected = false
28
+ 3.times do |i|
29
+ begin
30
+ s = TCPSocket.open(acceptor_host, acceptor_port)
31
+ s.print(port)
32
+ s.close
33
+ connected = true
34
+ start_debugger(options)
35
+ return
36
+ rescue => bt
37
+ $stderr.puts "#{Process.pid}: connection failed(#{i+1})"
38
+ $stderr.puts "Exception: #{bt}"
39
+ $stderr.puts bt.backtrace.map { |l| "\t#{l}" }.join("\n")
40
+ sleep 0.3
41
+ end unless connected
42
+ end
43
+ end
44
+
45
+ def start_debugger(options)
46
+ if Debugger.started?
47
+ # we're in forked child, only need to restart control thread
48
+ Debugger.breakpoints.clear
49
+ Debugger.control_thread = nil
50
+ end
51
+
52
+ if options.int_handler
53
+ # install interruption handler
54
+ trap('INT') { Debugger.interrupt_last }
55
+ end
56
+
57
+ # set options
58
+ Debugger.tracing = options.tracing
59
+ Debugger.wait_for_start = options.wait_for_start
60
+ Debugger.wait_connection = true
61
+ Debugger.printer = Printers::Xml.new
62
+ Debugger::Xml.logger = if options.debug_mode
63
+ Debugger::Xml::Ide::Logger.new
64
+ else
65
+ Debugger::Xml::FakeLogger.new
66
+ end
67
+ Debugger.start_remote_ide(options.host, options.port)
68
+ end
69
+
70
+
71
+ def find_free_port(host)
72
+ server = TCPServer.open(host, 0)
73
+ port = server.addr[1]
74
+ server.close
75
+ port
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,10 @@
1
+ if ENV['IDE_PROCESS_DISPATCHER']
2
+ require 'rubygems'
3
+ # todo: do we need these lines?
4
+ ENV['DEBUGGER_STORED_RUBYLIB'].split(File::PATH_SEPARATOR).each do |path|
5
+ next unless path =~ /debugger-xml|\/debugger\/|linecache/
6
+ $LOAD_PATH << path
7
+ end
8
+ require 'debugger/xml'
9
+ Debugger::Xml::MultiProcess.pre_child
10
+ end
@@ -1,5 +1,5 @@
1
1
  module Debugger
2
2
  module Xml
3
- VERSION = "0.2.0"
3
+ VERSION = "0.3.1"
4
4
  end
5
5
  end
data/test/thread_test.rb CHANGED
@@ -9,7 +9,7 @@ describe "Thread Command" do
9
9
  thnum = nil
10
10
  enter 'break 8', 'cont', 'thread list', release
11
11
  debug_file('thread') { thnum = Debugger.contexts.first.thnum }
12
- check_output_includes %{<threads><thread id="#{thnum}" status="run" current="yes"/></threads>}
12
+ check_output_includes %{<threads><thread id="#{thnum}" status="run" current="yes" pid="#{Process.pid}"/></threads>}
13
13
  end
14
14
 
15
15
  it "must show 3 available threads" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: debugger-xml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton Astashov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-14 00:00:00.000000000 Z
11
+ date: 2013-11-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: debugger
@@ -108,6 +108,7 @@ files:
108
108
  - lib/debugger/xml/extensions/commands/inspect.rb
109
109
  - lib/debugger/xml/extensions/commands/irb.rb
110
110
  - lib/debugger/xml/extensions/commands/kill.rb
111
+ - lib/debugger/xml/extensions/commands/threads.rb
111
112
  - lib/debugger/xml/extensions/commands/tmate.rb
112
113
  - lib/debugger/xml/extensions/commands/trace.rb
113
114
  - lib/debugger/xml/extensions/commands/variables.rb
@@ -119,6 +120,9 @@ files:
119
120
  - lib/debugger/xml/ide/interface.rb
120
121
  - lib/debugger/xml/ide/logger.rb
121
122
  - lib/debugger/xml/ide/processor.rb
123
+ - lib/debugger/xml/multiprocess/monkey.rb
124
+ - lib/debugger/xml/multiprocess/pre_child.rb
125
+ - lib/debugger/xml/multiprocess/starter.rb
122
126
  - lib/debugger/xml/version.rb
123
127
  - lib/debugger/xml/vim/control_command_processor.rb
124
128
  - lib/debugger/xml/vim/interface.rb