debugger-xml 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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