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.
- 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)
|