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