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,197 @@
1
+ require 'byebug/printers/base'
2
+ require 'builder'
3
+
4
+ module Byebug
5
+ module Printers
6
+ class Xml < Byebug::Printers::Base
7
+
8
+ def print(path, args = {})
9
+ case parts(path)[1]
10
+ when "errors"
11
+ print_error(path, args)
12
+ when "confirmations"
13
+ print_confirmation(path, args)
14
+ when "debug"
15
+ print_debug(path, args)
16
+ when "messages"
17
+ print_message(path, args)
18
+ else
19
+ print_general(path, args)
20
+ end
21
+ end
22
+
23
+ def print_collection(path, collection, &block)
24
+ settings = locate(path)
25
+ xml = ::Builder::XmlMarkup.new
26
+ tag = translate(settings["tag"])
27
+ xml.tag!("#{tag}s") do |xml|
28
+ array_of_args(collection, &block).each do |args|
29
+ xml.tag!(tag, translated_attributes(settings["attributes"], args))
30
+ end
31
+ end
32
+ end
33
+
34
+ def print_variables(variables, global_kind)
35
+ print_collection("variable.variable", variables) do |(key, value, kind), index|
36
+ Variable.new(key, value, kind || global_kind).to_hash
37
+ end
38
+ end
39
+
40
+ def print_instance_variables(object)
41
+ variables = if object.is_a?(Array)
42
+ object.each.with_index.map { |item, index| ["[#{index}]", item, 'instance'] }
43
+ elsif object.is_a?(Hash)
44
+ object.map { |key, value| [key.is_a?(String) ? "'#{key}'" : key.to_s, value, 'instance'] }
45
+ else
46
+ AllVariables.new(object).variables
47
+ end
48
+ print_variables(variables, nil)
49
+ end
50
+
51
+ private
52
+
53
+ def print_general(path, args)
54
+ settings = locate(path)
55
+ xml = ::Builder::XmlMarkup.new
56
+ tag = translate(settings["tag"], args)
57
+ attributes = translated_attributes(settings["attributes"], args)
58
+ xml.tag!(tag, attributes)
59
+ end
60
+
61
+ def print_debug(path, args)
62
+ translate(locate(path), args)
63
+ end
64
+
65
+ def print_error(path, args)
66
+ xml = ::Builder::XmlMarkup.new
67
+ xml.error { print_content(xml, path, args) }
68
+ end
69
+
70
+ def print_confirmation(path, args)
71
+ xml = ::Builder::XmlMarkup.new
72
+ xml.confirmation { print_content(xml, path, args) }
73
+ end
74
+
75
+ def print_message(path, args)
76
+ xml = ::Builder::XmlMarkup.new
77
+ xml.message { print_content(xml, path, args) }
78
+ end
79
+
80
+ def print_content(xml, path, args)
81
+ xml.text!(translate(locate(path), args))
82
+ end
83
+
84
+ def translated_attributes(attributes, args)
85
+ attributes.inject({}) do |hash, (key, value)|
86
+ hash[key] = translate(value, args)
87
+ hash
88
+ end
89
+ end
90
+
91
+ def contents_files
92
+ [File.expand_path(File.join("..", "texts", "xml.yml"), __FILE__)] + super
93
+ end
94
+
95
+ class Variable
96
+ attr_reader :name, :kind
97
+ def initialize(name, value, kind = nil)
98
+ @name = name.to_s
99
+ @value = value
100
+ @kind = kind
101
+ end
102
+
103
+ def has_children?
104
+ if @value.is_a?(Array) || @value.is_a?(Hash)
105
+ !@value.empty?
106
+ else
107
+ !@value.instance_variables.empty? || !@value.class.class_variables.empty?
108
+ end
109
+ rescue
110
+ false
111
+ end
112
+
113
+ def value
114
+ if @value.is_a?(Array) || @value.is_a?(Hash)
115
+ if has_children?
116
+ "#{@value.class} (#{@value.size} element(s))"
117
+ else
118
+ "Empty #{@value.class}"
119
+ end
120
+ else
121
+ value_str = @value.nil? ? 'nil' : @value.to_s
122
+ if !value_str.is_a?(String)
123
+ "ERROR: #{@value.class}.to_s method returns #{value_str.class}. Should return String."
124
+ elsif binary_data?(value_str)
125
+ "[Binary Data]"
126
+ else
127
+ value_str.gsub(/^(")(.*)(")$/, '\2')
128
+ end
129
+ end
130
+ rescue => e
131
+ "<raised exception: #{e}>"
132
+ end
133
+
134
+ def id
135
+ @value.respond_to?(:object_id) ? "%#+x" % @value.object_id : nil
136
+ rescue
137
+ nil
138
+ end
139
+
140
+ def type
141
+ @value.class
142
+ rescue
143
+ "Undefined"
144
+ end
145
+
146
+ def to_hash
147
+ {name: @name, kind: @kind, value: value, type: type, has_children: has_children?, id: id}
148
+ end
149
+
150
+ private
151
+
152
+ def binary_data?(string)
153
+ string.count("\x00-\x7F", "^ -~\t\r\n").fdiv(string.size) > 0.3 || string.index("\x00") unless string.empty?
154
+ end
155
+ end
156
+
157
+ class AllVariables
158
+ def initialize(object)
159
+ @object = object
160
+ @instance_binding = object.instance_eval{binding()}
161
+ @class_binding = object.class.class_eval('binding()')
162
+
163
+ @instance_variable_names = object.instance_variables
164
+ @self_variable_name = @instance_variable_names.delete('self')
165
+ @class_variable_names = object.class.class_variables
166
+ end
167
+
168
+ def variables
169
+ self_variables + instance_variables + class_variables
170
+ end
171
+
172
+ private
173
+
174
+ def instance_variables
175
+ @instance_variable_names.map do |var|
176
+ [var.to_s, (eval(var.to_s, @instance_binding) rescue "<raised exception>"), 'instance']
177
+ end
178
+ end
179
+
180
+ def self_variables
181
+ if @self_variable_name
182
+ [@self_variable_name, (eval(@self_variable_name, @instance_binding)), 'instance']
183
+ else
184
+ []
185
+ end
186
+ end
187
+
188
+ def class_variables
189
+ @class_variable_names.map do |var|
190
+ [var.to_s, (eval(var.to_s, @class_binding) rescue "<raised exception>"), 'class']
191
+ end
192
+ end
193
+ end
194
+
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,25 @@
1
+ module Debugger
2
+ class StartCommand < Command # :nodoc:
3
+ self.allow_in_control = true
4
+
5
+ def regexp
6
+ /^\s*(start)\s*$/ix
7
+ end
8
+
9
+ def execute
10
+ DebuggerXml.proceed
11
+ end
12
+
13
+ class << self
14
+ def help_command
15
+ 'start'
16
+ end
17
+
18
+ def help(cmd)
19
+ %{
20
+ run prog script
21
+ }
22
+ end
23
+ end
24
+ end
25
+ end
@@ -20,4 +20,18 @@ module Debugger
20
20
  alias_method :execute, :execute_with_xml
21
21
 
22
22
  end
23
+
24
+ class VarIdeCommand < Command
25
+ def regexp
26
+ /^\s*v(?:ar)?\s+ide\s*$/
27
+ end
28
+
29
+ def execute
30
+ locals = []
31
+ _self = @state.context.frame_self(@state.frame_pos)
32
+ locals << ['self', _self] unless _self.to_s == "main"
33
+ locals += @state.context.frame_locals(@state.frame_pos).sort.map { |key, value| [key, value] }
34
+ print prv(locals, 'instance')
35
+ end
36
+ end
23
37
  end
@@ -0,0 +1,91 @@
1
+ Dir.glob(File.expand_path("../debugger_xml/**/*.rb", __FILE__)).each { |f| require f }
2
+ if DEBUGGER_TYPE == :debugger
3
+ Dir.glob(File.expand_path("../debugger/**/*.rb", __FILE__)).each { |f| require f }
4
+ else
5
+ Dir.glob(File.expand_path("../byebug/**/*.rb", __FILE__)).each { |f| require f }
6
+ end
7
+
8
+ module DebuggerXml
9
+ class << self
10
+ attr_accessor :logger, :wait_for_start, :control_thread, :handler, :queue
11
+
12
+ def start_remote_ide(proxy, host, port)
13
+ return if @control_thread
14
+ @mutex = Mutex.new
15
+ @proceed = ConditionVariable.new
16
+ @queue = Queue.new
17
+ proxy.start
18
+ @control_thread = proxy.debug_thread_class.new do
19
+ server = TCPServer.new(host, port)
20
+ $stderr.printf "Fast Debugger (debugger-xml #{VERSION}) listens on #{host}:#{port}\n"
21
+ while (session = server.accept)
22
+ dispatcher = ENV['IDE_PROCESS_DISPATCHER']
23
+ if dispatcher && !dispatcher.include?(":")
24
+ ENV['IDE_PROCESS_DISPATCHER'] = "#{session.peeraddr[2]}:#{dispatcher}"
25
+ end
26
+ interface = DebuggerXml::Ide::Interface.new(session)
27
+ processor = DebuggerXml::Ide::ControlCommandProcessor.new(interface, proxy)
28
+ debugger_class.handler = DebuggerXml::Ide::Processor.new(interface, proxy)
29
+ processor.process_commands
30
+ end
31
+ end
32
+ @mutex.synchronize { @proceed.wait(@mutex) } if wait_for_start
33
+ end
34
+
35
+ def start_for_vim(proxy, options)
36
+ return if @control_thread
37
+ logger.puts("Going to daemonize")
38
+ daemonize!
39
+ logger.puts("Successfully daemonized")
40
+ $stdout.reopen(options.output_file, 'w')
41
+ $stdout.sync
42
+ $stderr.reopen($stdout)
43
+ logger.puts("Redirected stderr")
44
+ @mutex = Mutex.new
45
+ @proceed = ConditionVariable.new
46
+ @queue = Queue.new
47
+ proxy.start
48
+ logger.puts("Started debugger")
49
+ File.unlink(options.socket) if File.exist?(options.socket)
50
+ server = UNIXServer.new(options.socket)
51
+ Vim::Notification.new("establish_connection", options).send
52
+ logger.puts("Sent 'established_connection' command")
53
+ @control_thread = proxy.debug_thread_class.new do
54
+ begin
55
+ while (session = server.accept)
56
+ logger.puts("Accepted connection");
57
+ interface = Vim::Interface.new(session, options)
58
+ processor = Vim::ControlCommandProcessor.new(interface, proxy)
59
+ proxy.handler = Vim::Processor.new(processor, interface, proxy)
60
+ logger.puts("Going to process commands");
61
+ processor.process_commands
62
+ end
63
+ rescue Exception => e
64
+ logger.puts("INTERNAL ERROR!!! #{$!}") rescue nil
65
+ logger.puts($!.backtrace.map { |l| "\t#{l}" }.join("\n")) rescue nil
66
+ raise e
67
+ ensure
68
+ logger.puts("Closing server");
69
+ server.close
70
+ end
71
+ end
72
+ @mutex.synchronize { @proceed.wait(@mutex) } if wait_for_start
73
+ end
74
+
75
+ def proceed
76
+ return unless @mutex
77
+ @mutex.synchronize { @proceed.signal }
78
+ end
79
+
80
+ private
81
+
82
+ def daemonize!
83
+ pid = Process.fork
84
+ if pid
85
+ print pid
86
+ exit
87
+ end
88
+ end
89
+
90
+ end
91
+ end
@@ -0,0 +1,108 @@
1
+ module DebuggerXml
2
+ class ByebugProxy
3
+ def start
4
+ ::Byebug.start
5
+ end
6
+
7
+ def handler
8
+ ::Byebug.handler
9
+ end
10
+
11
+ def handler=(value)
12
+ ::Byebug.handler = value
13
+ end
14
+
15
+ def control_commands(interface)
16
+ control_command_classes = commands.select(&:allow_in_control)
17
+ state = ::Byebug::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
+ ::Byebug::CommandProcessor::State.new(commands, handler.context, [], handler.file, interface, handler.line)
23
+ end
24
+
25
+ def commands
26
+ ::Byebug::Command.commands
27
+ end
28
+
29
+ def event_commands(state)
30
+ event_command_classes.map { |cls| cls.new(state) }
31
+ end
32
+
33
+ def print(*args)
34
+ printer.print(*args)
35
+ end
36
+
37
+ def canonic_file(file)
38
+ ::Byebug::CommandProcessor.canonic_file(file)
39
+ end
40
+
41
+ def line_at(file, line)
42
+ end
43
+
44
+ def breakpoints
45
+ ::Byebug.breakpoints
46
+ end
47
+
48
+ def debug_thread?(context)
49
+ context && context.thread.is_a?(debug_thread_class)
50
+ end
51
+
52
+ def debug_thread_class
53
+ ::Byebug::DebugThread
54
+ end
55
+
56
+ def current_context
57
+ ::Byebug.current_context
58
+ end
59
+
60
+ def set_rdebug_script(file)
61
+ ::Byebug.const_set("RDEBUG_SCRIPT", file)
62
+ end
63
+
64
+ def set_prog_script(file)
65
+ ::Byebug.const_set("PROG_SCRIPT", file)
66
+ end
67
+
68
+ def set_argv(argv)
69
+ ::Byebug.const_set("ARGV", argv)
70
+ end
71
+
72
+ def interrupt_last
73
+ ::Byebug.interrupt_last
74
+ end
75
+
76
+ def tracing=(value)
77
+ ::Byebug.tracing = value
78
+ end
79
+
80
+ def wait_connection=(value)
81
+ ::Byebug.wait_connection = value
82
+ end
83
+
84
+ def printer=(value)
85
+ ::Byebug.printer = value
86
+ end
87
+
88
+ def debug_load
89
+ ::Byebug.debug_load(::Byebug::PROG_SCRIPT, false)
90
+ end
91
+
92
+ def inspect_command_class
93
+ ::Byebug::InspectCommand
94
+ end
95
+
96
+ private
97
+
98
+ def event_command_classes
99
+ commands
100
+ end
101
+
102
+ def printer
103
+ ::Byebug.printer
104
+ end
105
+
106
+ end
107
+ end
108
+