debugger-xml 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/bin/rdebug-ide +12 -9
- data/bin/rdebug-vim +30 -13
- data/debugger-xml.gemspec +7 -3
- data/lib/byebug/commands/frame.rb +16 -0
- data/lib/byebug/commands/help.rb +13 -0
- data/lib/byebug/commands/info.rb +13 -0
- data/lib/byebug/commands/inspect.rb +30 -0
- data/lib/byebug/commands/kill.rb +13 -0
- data/lib/byebug/commands/start.rb +25 -0
- data/lib/byebug/commands/threads.rb +10 -0
- data/lib/byebug/commands/trace.rb +13 -0
- data/lib/byebug/commands/variables.rb +54 -0
- data/lib/byebug/context_xml.rb +29 -0
- data/lib/byebug/printers/texts/xml.yml +122 -0
- data/lib/byebug/printers/xml.rb +197 -0
- data/lib/debugger/{xml/extensions/processor.rb → command_processor.rb} +0 -0
- data/lib/debugger/{xml/extensions/commands → commands}/edit.rb +0 -0
- data/lib/debugger/{xml/extensions/commands → commands}/frame.rb +0 -1
- data/lib/debugger/{xml/extensions/commands → commands}/help.rb +0 -0
- data/lib/debugger/{xml/extensions/commands → commands}/info.rb +0 -0
- data/lib/debugger/{xml/extensions/commands → commands}/inspect.rb +0 -0
- data/lib/debugger/{xml/extensions/commands → commands}/irb.rb +0 -0
- data/lib/debugger/{xml/extensions/commands → commands}/kill.rb +0 -0
- data/lib/debugger/commands/start.rb +25 -0
- data/lib/debugger/{xml/extensions/commands → commands}/threads.rb +0 -0
- data/lib/debugger/{xml/extensions/commands → commands}/tmate.rb +0 -0
- data/lib/debugger/{xml/extensions/commands → commands}/trace.rb +0 -0
- data/lib/debugger/{xml/extensions/commands → commands}/variables.rb +14 -0
- data/lib/debugger_xml.rb +91 -0
- data/lib/debugger_xml/byebug_proxy.rb +108 -0
- data/lib/debugger_xml/debugger_proxy.rb +115 -0
- data/lib/debugger_xml/fake_logger.rb +9 -0
- data/lib/debugger_xml/ide/control_command_processor.rb +69 -0
- data/lib/debugger_xml/ide/interface.rb +74 -0
- data/lib/debugger_xml/ide/logger.rb +9 -0
- data/lib/debugger_xml/ide/processor.rb +118 -0
- data/lib/debugger_xml/multiprocess/monkey.rb +47 -0
- data/lib/debugger_xml/multiprocess/pre_child.rb +79 -0
- data/lib/{debugger/xml → debugger_xml}/multiprocess/starter.rb +2 -2
- data/lib/debugger_xml/version.rb +3 -0
- data/lib/debugger_xml/vim/control_command_processor.rb +23 -0
- data/lib/debugger_xml/vim/interface.rb +46 -0
- data/lib/debugger_xml/vim/logger.rb +16 -0
- data/lib/debugger_xml/vim/notification.rb +35 -0
- data/lib/debugger_xml/vim/processor.rb +20 -0
- data/test/breakpoints_test.rb +0 -1
- data/test/ide/control_command_processor_test.rb +18 -13
- data/test/ide/processor_test.rb +11 -25
- data/test/printers/xml_test.rb +1 -0
- data/test/test_helper.rb +12 -3
- data/test/variables_test.rb +0 -1
- data/test/vim/control_command_processor_test.rb +4 -5
- data/test/vim/interface_test.rb +6 -6
- data/test/vim/notification_test.rb +3 -3
- data/test/vim/processor_test.rb +8 -8
- metadata +61 -48
- data/lib/debugger/xml.rb +0 -11
- data/lib/debugger/xml/extensions/ide_server.rb +0 -33
- data/lib/debugger/xml/extensions/vim_server.rb +0 -56
- data/lib/debugger/xml/fake_logger.rb +0 -11
- data/lib/debugger/xml/ide/control_command_processor.rb +0 -81
- data/lib/debugger/xml/ide/interface.rb +0 -72
- data/lib/debugger/xml/ide/logger.rb +0 -11
- data/lib/debugger/xml/ide/processor.rb +0 -94
- data/lib/debugger/xml/multiprocess/monkey.rb +0 -49
- data/lib/debugger/xml/multiprocess/pre_child.rb +0 -81
- data/lib/debugger/xml/version.rb +0 -5
- data/lib/debugger/xml/vim/control_command_processor.rb +0 -19
- data/lib/debugger/xml/vim/interface.rb +0 -42
- data/lib/debugger/xml/vim/logger.rb +0 -18
- data/lib/debugger/xml/vim/notification.rb +0 -37
- 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
|
@@ -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
|
data/test/breakpoints_test.rb
CHANGED
@@ -1,21 +1,26 @@
|
|
1
1
|
require_relative '../test_helper'
|
2
|
-
require '
|
2
|
+
require 'debugger_xml/ide/control_command_processor'
|
3
3
|
|
4
|
-
describe
|
4
|
+
describe DebuggerXml::Ide::ControlCommandProcessor do
|
5
5
|
include TestDsl
|
6
6
|
|
7
|
-
let(:klass) {
|
8
|
-
let(: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
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
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
|
|
data/test/ide/processor_test.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
require_relative '../test_helper'
|
2
|
-
require '
|
2
|
+
require 'debugger_xml/ide/processor'
|
3
3
|
|
4
|
-
describe
|
4
|
+
describe DebuggerXml::Ide::Processor do
|
5
5
|
include TestDsl
|
6
6
|
|
7
7
|
before { Thread.stubs(:stop) }
|
8
8
|
|
9
|
-
let(:klass) {
|
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}
|
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}
|
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
|
-
|
63
|
-
|
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 "
|
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(
|
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}
|
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
|
data/test/printers/xml_test.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -1,7 +1,16 @@
|
|
1
1
|
require 'minitest/autorun'
|
2
2
|
|
3
|
-
|
4
|
-
require 'debugger
|
3
|
+
DEBUGGER_TYPE = :debugger
|
4
|
+
require 'debugger'
|
5
|
+
require 'debugger_xml'
|
5
6
|
|
6
7
|
$debugger_test_dir = File.expand_path("..", __FILE__)
|
7
|
-
|
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
|
data/test/variables_test.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
require_relative '../test_helper'
|
2
|
-
require '
|
2
|
+
require 'debugger_xml/vim/control_command_processor'
|
3
3
|
|
4
|
-
describe
|
4
|
+
describe DebuggerXml::Vim::ControlCommandProcessor do
|
5
5
|
include TestDsl
|
6
6
|
|
7
|
-
let(:klass) {
|
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)
|