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,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
+