debugger-xml 0.3.3 → 0.4.0

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/bin/rdebug-ide +12 -9
  4. data/bin/rdebug-vim +30 -13
  5. data/debugger-xml.gemspec +7 -3
  6. data/lib/byebug/commands/frame.rb +16 -0
  7. data/lib/byebug/commands/help.rb +13 -0
  8. data/lib/byebug/commands/info.rb +13 -0
  9. data/lib/byebug/commands/inspect.rb +30 -0
  10. data/lib/byebug/commands/kill.rb +13 -0
  11. data/lib/byebug/commands/start.rb +25 -0
  12. data/lib/byebug/commands/threads.rb +10 -0
  13. data/lib/byebug/commands/trace.rb +13 -0
  14. data/lib/byebug/commands/variables.rb +54 -0
  15. data/lib/byebug/context_xml.rb +29 -0
  16. data/lib/byebug/printers/texts/xml.yml +122 -0
  17. data/lib/byebug/printers/xml.rb +197 -0
  18. data/lib/debugger/{xml/extensions/processor.rb → command_processor.rb} +0 -0
  19. data/lib/debugger/{xml/extensions/commands → commands}/edit.rb +0 -0
  20. data/lib/debugger/{xml/extensions/commands → commands}/frame.rb +0 -1
  21. data/lib/debugger/{xml/extensions/commands → commands}/help.rb +0 -0
  22. data/lib/debugger/{xml/extensions/commands → commands}/info.rb +0 -0
  23. data/lib/debugger/{xml/extensions/commands → commands}/inspect.rb +0 -0
  24. data/lib/debugger/{xml/extensions/commands → commands}/irb.rb +0 -0
  25. data/lib/debugger/{xml/extensions/commands → commands}/kill.rb +0 -0
  26. data/lib/debugger/commands/start.rb +25 -0
  27. data/lib/debugger/{xml/extensions/commands → commands}/threads.rb +0 -0
  28. data/lib/debugger/{xml/extensions/commands → commands}/tmate.rb +0 -0
  29. data/lib/debugger/{xml/extensions/commands → commands}/trace.rb +0 -0
  30. data/lib/debugger/{xml/extensions/commands → commands}/variables.rb +14 -0
  31. data/lib/debugger_xml.rb +91 -0
  32. data/lib/debugger_xml/byebug_proxy.rb +108 -0
  33. data/lib/debugger_xml/debugger_proxy.rb +115 -0
  34. data/lib/debugger_xml/fake_logger.rb +9 -0
  35. data/lib/debugger_xml/ide/control_command_processor.rb +69 -0
  36. data/lib/debugger_xml/ide/interface.rb +74 -0
  37. data/lib/debugger_xml/ide/logger.rb +9 -0
  38. data/lib/debugger_xml/ide/processor.rb +118 -0
  39. data/lib/debugger_xml/multiprocess/monkey.rb +47 -0
  40. data/lib/debugger_xml/multiprocess/pre_child.rb +79 -0
  41. data/lib/{debugger/xml → debugger_xml}/multiprocess/starter.rb +2 -2
  42. data/lib/debugger_xml/version.rb +3 -0
  43. data/lib/debugger_xml/vim/control_command_processor.rb +23 -0
  44. data/lib/debugger_xml/vim/interface.rb +46 -0
  45. data/lib/debugger_xml/vim/logger.rb +16 -0
  46. data/lib/debugger_xml/vim/notification.rb +35 -0
  47. data/lib/debugger_xml/vim/processor.rb +20 -0
  48. data/test/breakpoints_test.rb +0 -1
  49. data/test/ide/control_command_processor_test.rb +18 -13
  50. data/test/ide/processor_test.rb +11 -25
  51. data/test/printers/xml_test.rb +1 -0
  52. data/test/test_helper.rb +12 -3
  53. data/test/variables_test.rb +0 -1
  54. data/test/vim/control_command_processor_test.rb +4 -5
  55. data/test/vim/interface_test.rb +6 -6
  56. data/test/vim/notification_test.rb +3 -3
  57. data/test/vim/processor_test.rb +8 -8
  58. metadata +61 -48
  59. data/lib/debugger/xml.rb +0 -11
  60. data/lib/debugger/xml/extensions/ide_server.rb +0 -33
  61. data/lib/debugger/xml/extensions/vim_server.rb +0 -56
  62. data/lib/debugger/xml/fake_logger.rb +0 -11
  63. data/lib/debugger/xml/ide/control_command_processor.rb +0 -81
  64. data/lib/debugger/xml/ide/interface.rb +0 -72
  65. data/lib/debugger/xml/ide/logger.rb +0 -11
  66. data/lib/debugger/xml/ide/processor.rb +0 -94
  67. data/lib/debugger/xml/multiprocess/monkey.rb +0 -49
  68. data/lib/debugger/xml/multiprocess/pre_child.rb +0 -81
  69. data/lib/debugger/xml/version.rb +0 -5
  70. data/lib/debugger/xml/vim/control_command_processor.rb +0 -19
  71. data/lib/debugger/xml/vim/interface.rb +0 -42
  72. data/lib/debugger/xml/vim/logger.rb +0 -18
  73. data/lib/debugger/xml/vim/notification.rb +0 -37
  74. data/lib/debugger/xml/vim/processor.rb +0 -22
@@ -0,0 +1,79 @@
1
+ module DebuggerXml
2
+ module MultiProcess
3
+ class << self
4
+ def pre_child
5
+ return unless ENV['IDE_PROCESS_DISPATCHER']
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
+ DebuggerXml.logger = if options.debug_mode
63
+ Debugger::Xml::Ide::Logger.new
64
+ else
65
+ Debugger::Xml::FakeLogger.new
66
+ end
67
+ DebuggerXml.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
@@ -5,6 +5,6 @@ if ENV['IDE_PROCESS_DISPATCHER']
5
5
  next unless path =~ /debugger-xml|\/debugger\/|linecache/
6
6
  $LOAD_PATH << path
7
7
  end
8
- require 'debugger/xml'
9
- Debugger::Xml::MultiProcess.pre_child
8
+ require 'debugger_xml'
9
+ DebuggerXml::MultiProcess.pre_child
10
10
  end
@@ -0,0 +1,3 @@
1
+ module DebuggerXml
2
+ VERSION = "0.4.0"
3
+ end
@@ -0,0 +1,23 @@
1
+ require 'debugger_xml/ide/control_command_processor'
2
+
3
+ module DebuggerXml
4
+ module Vim
5
+
6
+ class ControlCommandProcessor < Ide::ControlCommandProcessor
7
+ def initialize(*args)
8
+ super(*args)
9
+ @mutex = Mutex.new
10
+ end
11
+
12
+ private
13
+
14
+ def process_command(*args)
15
+ @mutex.synchronize do
16
+ super(*args)
17
+ @interface.send_response
18
+ end
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,46 @@
1
+ require 'debugger_xml/ide/interface'
2
+
3
+ module DebuggerXml
4
+ module Vim
5
+ class Interface < Ide::Interface
6
+ def initialize(socket, options)
7
+ super(socket)
8
+ @options = options
9
+ @output = []
10
+ end
11
+
12
+ def print(*args)
13
+ escaped_args = escape_input(args)
14
+ value = escaped_args.first % escaped_args[1..-1]
15
+ DebuggerXml.logger.puts("Going to print: #{value}")
16
+ @output << sprintf(value)
17
+ end
18
+
19
+ def send_response
20
+ create_directory(@options.file)
21
+ message = @output.join(@options.separator)
22
+ @output.clear
23
+ unless message.empty?
24
+ File.open(@options.file, 'w') do |f|
25
+ f.puts(message)
26
+ end
27
+ Notification.new("receive_command", @options).send
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def create_directory(file)
34
+ dir = File.dirname(file)
35
+ Dir.mkdir(dir) unless File.exist?(dir) && File.directory?(dir)
36
+ end
37
+
38
+ def escape_input(args)
39
+ new_args = args.dup
40
+ new_args.first.gsub!("%", "%%") if args.first.is_a?(String)
41
+ new_args
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,16 @@
1
+ module DebuggerXml
2
+ module Vim
3
+ class Logger
4
+ def initialize(logger_file)
5
+ @logger_file = logger_file
6
+ end
7
+
8
+ def puts(string)
9
+ File.open(@logger_file, 'a') do |f|
10
+ # match vim redir style new lines, rather than trailing
11
+ f << "\ndebugger-xml, #{Time.now.strftime("%H:%M:%S")} : #{string.chomp}"
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,35 @@
1
+ module DebuggerXml
2
+ module Vim
3
+ class Notification
4
+
5
+ def initialize(command, options)
6
+ @command = command
7
+ @executable = options.vim_executable
8
+ @servername = options.vim_servername
9
+ @debug_mode = options.debug_mode
10
+ @logger_file = options.logger_file
11
+ end
12
+
13
+ def send
14
+ command = ":call RubyDebugger.#{@command}()"
15
+ starter = "<C-\\\\>"
16
+ sys_cmd = "#{@executable} --servername #{@servername} -u NONE -U NONE " +
17
+ "--remote-send \"#{starter}<C-N>#{command}<CR>\""
18
+ log("Executing command: #{sys_cmd}")
19
+ system(sys_cmd);
20
+ end
21
+
22
+ private
23
+
24
+ def log(string)
25
+ if @debug_mode
26
+ File.open(@logger_file, 'a') do |f|
27
+ # match vim redir style new lines, rather than trailing
28
+ f << "\ndebugger-xml, #{Time.now.strftime("%H:%M:%S")} : #{string.chomp}"
29
+ end
30
+ end
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ require 'debugger_xml/ide/processor'
2
+
3
+ module DebuggerXml
4
+ module Vim
5
+
6
+ class Processor < Ide::Processor
7
+ def initialize(control_command_processor, *args)
8
+ @control_command_processor = control_command_processor
9
+ super(*args)
10
+ end
11
+
12
+ def stop_thread
13
+ @control_command_processor.process_command("where")
14
+ @control_command_processor.process_command("var ide")
15
+ super
16
+ end
17
+ end
18
+
19
+ end
20
+ end
@@ -2,7 +2,6 @@ require_relative 'test_helper'
2
2
 
3
3
  describe "Breakpoints" do
4
4
  include TestDsl
5
- temporary_change_method_value(Debugger, :printer, Printers::Xml.new)
6
5
 
7
6
  describe "setting breakpoint in the current file" do
8
7
  it "must return right response" do
@@ -1,21 +1,26 @@
1
1
  require_relative '../test_helper'
2
- require 'debugger/xml/ide/control_command_processor'
2
+ require 'debugger_xml/ide/control_command_processor'
3
3
 
4
- describe Debugger::Xml::Ide::ControlCommandProcessor do
4
+ describe DebuggerXml::Ide::ControlCommandProcessor do
5
5
  include TestDsl
6
6
 
7
- let(:klass) { Debugger::Xml::Ide::ControlCommandProcessor }
8
- let(:interface) { Debugger.handler.interface }
7
+ let(:klass) { DebuggerXml::Ide::ControlCommandProcessor }
8
+ let(:interface) { $proxy.handler.interface }
9
9
  let(:file) { fullpath('jump') }
10
10
  let(:context) { stub(frame_binding: stub, stop_reason: nil, thread: stub, thnum: 1, stack_size: 2, dead?: false) }
11
- subject { klass.new(interface) }
12
- temporary_change_method_value(Debugger, :handler, Debugger::Xml::Ide::Processor.new(TestInterface.new))
11
+ subject { klass.new(interface, $proxy) }
13
12
 
14
13
  before do
15
14
  Thread.stubs(:stop)
16
- Debugger.handler.instance_variable_set("@context", context)
17
- Debugger.handler.instance_variable_set("@file", file)
18
- Debugger.handler.instance_variable_set("@line", 30)
15
+ @handler = $proxy.handler
16
+ $proxy.handler = DebuggerXml::Ide::Processor.new(TestInterface.new, $proxy)
17
+ $proxy.handler.instance_variable_set("@context", context)
18
+ $proxy.handler.instance_variable_set("@file", file)
19
+ $proxy.handler.instance_variable_set("@line", 30)
20
+ end
21
+
22
+ after do
23
+ $proxy.handler = @handler
19
24
  end
20
25
 
21
26
  it "must process a control command" do
@@ -34,22 +39,22 @@ describe Debugger::Xml::Ide::ControlCommandProcessor do
34
39
  it "must show error if there is no such command" do
35
40
  enter 'bla'
36
41
  subject.process_commands
37
- check_output_includes "Unknown command: bla"
42
+ check_output_includes "<error>Unknown command: bla</error>"
38
43
  end
39
44
 
40
45
  it "must show error if context is dead" do
41
46
  context.expects(:dead?).returns(true)
42
47
  enter 'step'
43
48
  subject.process_commands
44
- check_output_includes "Command is unavailable"
49
+ check_output_includes "<error>Command is unavailable</error>"
45
50
  end
46
51
 
47
52
  it "must show error if no suspended thread" do
48
- Debugger.handler.stubs(:at_line?).returns(false)
53
+ $proxy.handler.stubs(:at_line?).returns(false)
49
54
  enter 'step'
50
55
  subject.process_commands
51
56
  check_output_includes(
52
- "There is no thread suspended at the time and therefore no context to execute 'step'",
57
+ "<error>There is no thread suspended at the time and therefore no context to execute 'step'</error>",
53
58
  interface.error_queue)
54
59
  end
55
60
 
@@ -1,17 +1,17 @@
1
1
  require_relative '../test_helper'
2
- require 'debugger/xml/ide/processor'
2
+ require 'debugger_xml/ide/processor'
3
3
 
4
- describe Debugger::Xml::Ide::Processor do
4
+ describe DebuggerXml::Ide::Processor do
5
5
  include TestDsl
6
6
 
7
7
  before { Thread.stubs(:stop) }
8
8
 
9
- let(:klass) { Debugger::Xml::Ide::Processor }
9
+ let(:klass) { DebuggerXml::Ide::Processor }
10
10
  let(:interface) { TestInterface.new }
11
11
  let(:breakpoint) { stub }
12
12
  let(:context) { stub(thread: nil, stop_reason: nil, thnum: 1, stack_size: 2) }
13
13
  let(:file) { fullpath('jump') }
14
- subject { klass.new(interface) }
14
+ subject { klass.new(interface, $proxy) }
15
15
 
16
16
  describe "#at_breakpoint" do
17
17
  it "must assign breakpoint to instance variable" do
@@ -35,20 +35,13 @@ describe Debugger::Xml::Ide::Processor do
35
35
  describe "print current position" do
36
36
  it "must print if context is nil" do
37
37
  subject.at_line(nil, file, 30)
38
- check_output_includes "#{file}:30"
39
- end
40
-
41
- it "must print in xml" do
42
- temporary_change_method_value(Debugger, :printer, Printers::Xml.new) do
43
- subject.at_line(nil, file, 30)
44
- check_output_includes %{<suspended file="#{file}" line="30" threadId="" frames=""/>}
45
- end
38
+ check_output_includes %{<suspended file="#{file}" line="30" threadId="" frames=""/>}
46
39
  end
47
40
 
48
41
  it "must print if stop reason is :step" do
49
42
  context.stubs(:stop_reason).returns(:step)
50
43
  subject.at_line(context, file, 30)
51
- check_output_includes "#{file}:30"
44
+ check_output_includes %{<suspended file="#{file}" line="30" threadId="1" frames="2"/>}
52
45
  end
53
46
 
54
47
  it "must clear instance variables after resuming thread" do
@@ -59,26 +52,19 @@ describe Debugger::Xml::Ide::Processor do
59
52
 
60
53
  describe "print breakpoint after at_breakpoint" do
61
54
  before do
62
- Debugger.stubs(:breakpoints).returns([breakpoint])
63
- Debugger.stubs(:current_context).returns(stub(thnum: 1))
55
+ $proxy.stubs(:breakpoints).returns([breakpoint])
56
+ $proxy.stubs(:current_context).returns(stub(thnum: 1))
64
57
  subject.instance_variable_set("@last_breakpoint", breakpoint)
65
58
  end
66
59
 
67
60
  it "must print in plain text" do
68
61
  subject.at_line(context, file, 30)
69
- check_output_includes "Breakpoint 1 at #{file}:30"
70
- end
71
-
72
- it "must print in xml" do
73
- temporary_change_method_value(Debugger, :printer, Printers::Xml.new) do
74
- subject.at_line(context, file, 30)
75
- check_output_includes %{<breakpoint file="#{file}" line="30" threadId="1"/>}
76
- end
62
+ check_output_includes %{<breakpoint file="#{file}" line="30" threadId="1"/>}
77
63
  end
78
64
  end
79
65
 
80
66
  it "must show error if current thread is DebugThread" do
81
- context.stubs(:thread).returns(Debugger::DebugThread.new {})
67
+ context.stubs(:thread).returns($proxy.debug_thread_class.new {})
82
68
  subject.at_line(context, file, 30)
83
69
  check_output_includes /DebuggerThread are not supposed to be traced/
84
70
  end
@@ -106,7 +92,7 @@ describe Debugger::Xml::Ide::Processor do
106
92
 
107
93
  it "prints current file and line" do
108
94
  subject.at_return(context, file, 30)
109
- check_output_includes "#{file}:30"
95
+ check_output_includes %{<suspended file="#{file}" line="30" threadId="1" frames="2"/>}
110
96
  end
111
97
 
112
98
  it "stops the thread" do
@@ -1,4 +1,5 @@
1
1
  require_relative '../test_helper'
2
+ require 'ostruct'
2
3
 
3
4
  describe "Printers::Xml" do
4
5
  include PrinterHelpers
@@ -1,7 +1,16 @@
1
1
  require 'minitest/autorun'
2
2
 
3
- require 'debugger/xml'
4
- require 'debugger/test'
3
+ DEBUGGER_TYPE = :debugger
4
+ require 'debugger'
5
+ require 'debugger_xml'
5
6
 
6
7
  $debugger_test_dir = File.expand_path("..", __FILE__)
7
- Debugger::Xml.logger = Debugger::Xml::FakeLogger.new
8
+ $proxy = DebuggerXml::DebuggerProxy.new
9
+
10
+ MiniTest::Unit::TestCase.add_setup_hook do
11
+ $proxy.printer = Printers::Xml.new
12
+ end
13
+
14
+ require 'debugger/test'
15
+
16
+ DebuggerXml.logger = DebuggerXml::FakeLogger.new
@@ -2,7 +2,6 @@ require_relative 'test_helper'
2
2
 
3
3
  describe "Variables Command" do
4
4
  include TestDsl
5
- temporary_change_method_value(Debugger, :printer, Printers::Xml.new)
6
5
 
7
6
  describe "constants" do
8
7
  it "must show constants" do
@@ -1,15 +1,14 @@
1
1
  require_relative '../test_helper'
2
- require 'debugger/xml/vim/control_command_processor'
2
+ require 'debugger_xml/vim/control_command_processor'
3
3
 
4
- describe Debugger::Xml::Vim::ControlCommandProcessor do
4
+ describe DebuggerXml::Vim::ControlCommandProcessor do
5
5
  include TestDsl
6
6
 
7
- let(:klass) { Debugger::Xml::Vim::ControlCommandProcessor }
7
+ let(:klass) { DebuggerXml::Vim::ControlCommandProcessor }
8
8
  let(:interface) { Debugger.handler.interface }
9
9
  let(:file) { fullpath('jump') }
10
10
  let(:context) { stub(frame_binding: stub, stop_reason: nil, thread: stub, thnum: 1, stack_size: 2, dead?: false) }
11
- subject { klass.new(interface) }
12
- temporary_change_method_value(Debugger, :handler, Debugger::Xml::Ide::Processor.new(TestInterface.new))
11
+ subject { klass.new(interface, $proxy) }
13
12
 
14
13
  before do
15
14
  Thread.stubs(:stop)