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,115 @@
1
+ module DebuggerXml
2
+ class DebuggerProxy
3
+ def start
4
+ ::Debugger.start
5
+ end
6
+
7
+ def handler
8
+ ::Debugger.handler
9
+ end
10
+
11
+ def handler=(value)
12
+ ::Debugger.handler = value
13
+ end
14
+
15
+ def control_commands(interface)
16
+ control_command_classes = commands.select(&:allow_in_control)
17
+ state = ::Debugger::ControlCommandProcessor::State.new(interface, control_command_classes)
18
+ control_command_classes.map { |cmd| cmd.new(state) }
19
+ end
20
+
21
+ def build_command_processor_state(interface)
22
+ ::Debugger::CommandProcessor::State.new do |s|
23
+ s.context = handler.context
24
+ s.file = handler.file
25
+ s.line = handler.line
26
+ s.binding = handler.context.frame_binding(0)
27
+ s.interface = interface
28
+ s.commands = event_command_classes
29
+ end
30
+ end
31
+
32
+ def commands
33
+ ::Debugger::Command.commands
34
+ end
35
+
36
+ def event_commands(state)
37
+ event_command_classes.map { |cls| cls.new(state) }
38
+ end
39
+
40
+ def print(*args)
41
+ printer.print(*args)
42
+ end
43
+
44
+ def canonic_file(file)
45
+ ::Debugger::CommandProcessor.canonic_file(file)
46
+ end
47
+
48
+ def line_at(file, line)
49
+ ::Debugger.line_at(file, line)
50
+ end
51
+
52
+ def breakpoints
53
+ ::Debugger.breakpoints
54
+ end
55
+
56
+ def debug_thread?(context)
57
+ context && context.thread.is_a?(debug_thread_class)
58
+ end
59
+
60
+ def debug_thread_class
61
+ ::Debugger::DebugThread
62
+ end
63
+
64
+ def current_context
65
+ ::Debugger.current_context
66
+ end
67
+
68
+ def set_rdebug_script(file)
69
+ ::Debugger.const_set("RDEBUG_SCRIPT", file)
70
+ end
71
+
72
+ def set_prog_script(file)
73
+ ::Debugger.const_set("PROG_SCRIPT", file)
74
+ end
75
+
76
+ def set_argv(argv)
77
+ ::Debugger.const_set("ARGV", argv)
78
+ end
79
+
80
+ def interrupt_last
81
+ ::Debugger.interrupt_last
82
+ end
83
+
84
+ def tracing=(value)
85
+ ::Debugger.tracing = value
86
+ end
87
+
88
+ def wait_connection=(value)
89
+ ::Debugger.wait_connection = value
90
+ end
91
+
92
+ def printer=(value)
93
+ ::Debugger.printer = value
94
+ end
95
+
96
+ def debug_load
97
+ ::Debugger.debug_load(::Debugger::PROG_SCRIPT, false, false)
98
+ end
99
+
100
+ def inspect_command_class
101
+ ::Debugger::InspectCommand
102
+ end
103
+
104
+ private
105
+
106
+ def event_command_classes
107
+ commands.select(&:event)
108
+ end
109
+
110
+ def printer
111
+ ::Debugger.printer
112
+ end
113
+
114
+ end
115
+ end
@@ -0,0 +1,9 @@
1
+ module DebuggerXml
2
+ class FakeLogger
3
+ def initialize(*args)
4
+ end
5
+
6
+ def puts(*args)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,69 @@
1
+ module DebuggerXml
2
+ module Ide
3
+ class ControlCommandProcessor
4
+
5
+ def initialize(interface, proxy)
6
+ @interface = interface
7
+ @proxy = proxy
8
+ end
9
+
10
+ def process_commands
11
+ while input = @interface.read_command
12
+ process_input(input)
13
+ end
14
+ rescue IOError, Errno::EPIPE
15
+ rescue Exception
16
+ @interface.print("INTERNAL ERROR!!! #{$!}\n") rescue nil
17
+ @interface.print($!.backtrace.map { |l| "\t#{l}" }.join("\n")) rescue nil
18
+ ensure
19
+ @interface.close
20
+ end
21
+
22
+ def process_command(cmd)
23
+ catch(:debug_error) do
24
+ if matched_cmd = @proxy.control_commands(@interface).find { |c| c.match(cmd) }
25
+ matched_cmd.execute
26
+ else
27
+ process_context_commands(cmd)
28
+ end
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def process_input(input)
35
+ split_commands(input).each do |cmd|
36
+ process_command(cmd)
37
+ end
38
+ end
39
+
40
+ def process_context_commands(input)
41
+ unless @proxy.handler.at_line?
42
+ @interface.errmsg(@proxy.print("base.errors.no_suspended_thread", input: input))
43
+ return
44
+ end
45
+ state = @proxy.build_command_processor_state(@interface)
46
+ event_commands = @proxy.event_commands(state)
47
+ catch(:debug_error) do
48
+ if cmd = event_commands.find { |c| c.match(input) }
49
+ if state.context.dead? && cmd.class.need_context
50
+ @interface.print(@proxy.print("base.errors.command_unavailable"))
51
+ else
52
+ cmd.execute
53
+ end
54
+ else
55
+ @interface.print(@proxy.print("base.errors.unknown_command", input: input))
56
+ end
57
+ end
58
+ state.context.thread.run if state.proceed?
59
+ end
60
+
61
+ # Split commands like this:
62
+ # split_commands("abc;def\\;ghi;jkl") => ["abc", "def;ghi", "jkl"]
63
+ def split_commands(input)
64
+ input.split(/(?<!\\);/).map { |e| e.gsub("\\;", ";") }
65
+ end
66
+
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,74 @@
1
+ module DebuggerXml
2
+ module Ide
3
+ class Interface
4
+ attr_accessor :command_queue
5
+ attr_accessor :histfile
6
+ attr_accessor :history_save
7
+ attr_accessor :history_length
8
+ attr_accessor :restart_file
9
+
10
+ def initialize(socket)
11
+ @command_queue = []
12
+ @socket = socket
13
+ @history_save = false
14
+ @history_length = 256
15
+ @histfile = ''
16
+ @restart_file = nil
17
+ end
18
+
19
+ def close
20
+ @socket.close
21
+ rescue Exception
22
+ end
23
+
24
+ def print_debug(msg)
25
+ STDOUT.puts(msg)
26
+ end
27
+
28
+ def errmsg(*args)
29
+ print(*args)
30
+ end
31
+
32
+ def confirm(prompt)
33
+ true
34
+ end
35
+
36
+ def finalize
37
+ close
38
+ end
39
+
40
+ # Workaround for JRuby issue http://jira.codehaus.org/browse/JRUBY-2063
41
+ def non_blocking_gets
42
+ loop do
43
+ result, _, _ = IO.select([@socket], nil, nil, 0.2)
44
+ next unless result
45
+ return result[0].gets
46
+ end
47
+ end
48
+
49
+ def read_command(*args)
50
+ result = non_blocking_gets
51
+ raise IOError unless result
52
+ result.chomp.tap do |r|
53
+ DebuggerXml.logger.puts("Read command: #{r}")
54
+ end
55
+ end
56
+
57
+ def readline_support?
58
+ false
59
+ end
60
+
61
+ def print(*args)
62
+ escaped_args = escape_input(args)
63
+ value = escaped_args.first % escaped_args[1..-1]
64
+ DebuggerXml.logger.puts("Going to print: #{value}")
65
+ @socket.print(value)
66
+ end
67
+
68
+ def puts(*args)
69
+ print(*args)
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,9 @@
1
+ module DebuggerXml
2
+ module Ide
3
+ class Logger
4
+ def puts(string)
5
+ $stderr.puts(string)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,118 @@
1
+ module DebuggerXml
2
+ module Ide
3
+ class Processor
4
+ class << self
5
+ private
6
+
7
+ # Copied from debugger gem.
8
+ def protect(mname)
9
+ alias_method "__#{mname}", mname
10
+ module_eval %{
11
+ def #{mname}(*args)
12
+ @mutex.synchronize do
13
+ return unless @interface
14
+ __#{mname}(*args)
15
+ end
16
+ rescue IOError, Errno::EPIPE
17
+ self.interface = nil
18
+ rescue SignalException
19
+ raise
20
+ rescue Exception
21
+ @interface.print "INTERNAL ERROR!!! #\{$!\}\n" rescue nil
22
+ @interface.print $!.backtrace.map{|l| "\t#\{l\}"}.join("\n") rescue nil
23
+ end
24
+ }
25
+ end
26
+ end
27
+
28
+ attr_reader :context, :file, :line, :display
29
+ attr_accessor :interface
30
+
31
+ def initialize(interface, proxy)
32
+ @mutex = Mutex.new
33
+ @interface = interface
34
+ @proxy = proxy
35
+ @display = []
36
+ end
37
+
38
+ def at_breakpoint(context, breakpoint)
39
+ raise "@last_breakpoint supposed to be nil. is #{@last_breakpoint}" if @last_breakpoint
40
+ # at_breakpoint is immediately followed by #at_line event. So postpone breakpoint printing until #at_line.
41
+ @last_breakpoint = breakpoint
42
+ end
43
+ protect :at_breakpoint
44
+
45
+ # TODO: Catching exceptions doesn't work so far, need to fix
46
+ def at_catchpoint(context, excpt)
47
+ end
48
+
49
+ # We don't have tracing for IDE
50
+ def at_tracing(*args)
51
+ end
52
+
53
+ def at_line(context, file, line)
54
+ if context.nil? || context.stop_reason == :step
55
+ print_file_line(context, file, line)
56
+ end
57
+ line_event(context, file, line)
58
+ end
59
+ protect :at_line
60
+
61
+ def at_return(context, file, line)
62
+ print_file_line(context, file, line)
63
+ context.stop_frame = -1
64
+ line_event(context, file, line)
65
+ end
66
+
67
+ def at_line?
68
+ !!@line
69
+ end
70
+
71
+ private
72
+
73
+ def print_file_line(context, file, line)
74
+ @interface.print(
75
+ @proxy.print(
76
+ "stop.suspend",
77
+ file: @proxy.canonic_file(file),
78
+ line_number: line,
79
+ line: @proxy.line_at(file, line),
80
+ thnum: context && context.thnum,
81
+ frames: context && context.stack_size
82
+ )
83
+ )
84
+ end
85
+
86
+ def line_event(context, file, line)
87
+ @line = line
88
+ @file = file
89
+ @context = context
90
+ if @last_breakpoint
91
+ # followed after #at_breakpoint in the same thread. Print breakpoint
92
+ # now when @line, @file and @context are correctly set to prevent race
93
+ # condition with `control thread'.
94
+ n = @proxy.breakpoints.index(@last_breakpoint) + 1
95
+ @interface.print(@proxy.print("breakpoints.stop_at_breakpoint",
96
+ id: n, file: @file, line: @line, thread_id: @proxy.current_context.thnum
97
+ ))
98
+ end
99
+ if @proxy.debug_thread?(@context)
100
+ raise @proxy.print("thread.errors.debug_trace", thread: @context.thread)
101
+ end
102
+ # will be resumed by commands like `step', `next', `continue', `finish'
103
+ # from `control thread'
104
+ stop_thread
105
+ ensure
106
+ @line = nil
107
+ @file = nil
108
+ @context = nil
109
+ @last_breakpoint = nil
110
+ @proxy.inspect_command_class.clear_references
111
+ end
112
+
113
+ def stop_thread
114
+ Thread.stop
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,47 @@
1
+ module DebuggerXml
2
+ module MultiProcess
3
+ def self.create_mp_fork(private=false)
4
+ %Q{
5
+ alias pre_debugger_fork fork
6
+
7
+ #{private ? "private" : ""}
8
+ def fork(*args)
9
+ if block_given?
10
+ return pre_debugger_fork{DebuggerXml::MultiProcess::pre_child; yield}
11
+ end
12
+ result = pre_debugger_fork
13
+ DebuggerXml::MultiProcess::pre_child unless result
14
+ result
15
+ end
16
+ }
17
+ end
18
+
19
+ def self.create_mp_exec(private=false)
20
+ %Q{
21
+ alias pre_debugger_exec exec
22
+
23
+ #{private ? "private" : ""}
24
+ def exec(*args)
25
+ Debugger.handler.interface.close
26
+ pre_debugger_exec(*args)
27
+ end
28
+ }
29
+ end
30
+ end
31
+ end
32
+
33
+ module Kernel
34
+ class << self
35
+ module_eval DebuggerXml::MultiProcess.create_mp_fork
36
+ module_eval DebuggerXml::MultiProcess.create_mp_exec
37
+ end
38
+ module_eval DebuggerXml::MultiProcess.create_mp_fork(true)
39
+ module_eval DebuggerXml::MultiProcess.create_mp_exec(true)
40
+ end
41
+
42
+ module Process
43
+ class << self
44
+ module_eval DebuggerXml::MultiProcess.create_mp_fork
45
+ module_eval DebuggerXml::MultiProcess.create_mp_exec
46
+ end
47
+ end