ruby-debug-ide-docker 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +75 -0
  3. data/ChangeLog.archive +1073 -0
  4. data/ChangeLog.md +594 -0
  5. data/Gemfile +28 -0
  6. data/MIT-LICENSE +24 -0
  7. data/Rakefile +42 -0
  8. data/bin/gdb_wrapper +96 -0
  9. data/bin/rdebug-ide +183 -0
  10. data/ext/mkrf_conf.rb +48 -0
  11. data/lib/ruby-debug-ide.rb +173 -0
  12. data/lib/ruby-debug-ide/attach/debugger_loader.rb +20 -0
  13. data/lib/ruby-debug-ide/attach/gdb.rb +73 -0
  14. data/lib/ruby-debug-ide/attach/lldb.rb +71 -0
  15. data/lib/ruby-debug-ide/attach/native_debugger.rb +133 -0
  16. data/lib/ruby-debug-ide/attach/process_thread.rb +54 -0
  17. data/lib/ruby-debug-ide/attach/util.rb +115 -0
  18. data/lib/ruby-debug-ide/command.rb +177 -0
  19. data/lib/ruby-debug-ide/commands/breakpoints.rb +128 -0
  20. data/lib/ruby-debug-ide/commands/catchpoint.rb +64 -0
  21. data/lib/ruby-debug-ide/commands/condition.rb +51 -0
  22. data/lib/ruby-debug-ide/commands/control.rb +158 -0
  23. data/lib/ruby-debug-ide/commands/enable.rb +203 -0
  24. data/lib/ruby-debug-ide/commands/eval.rb +64 -0
  25. data/lib/ruby-debug-ide/commands/expression_info.rb +71 -0
  26. data/lib/ruby-debug-ide/commands/file_filtering.rb +107 -0
  27. data/lib/ruby-debug-ide/commands/frame.rb +155 -0
  28. data/lib/ruby-debug-ide/commands/inspect.rb +25 -0
  29. data/lib/ruby-debug-ide/commands/jump.rb +73 -0
  30. data/lib/ruby-debug-ide/commands/load.rb +18 -0
  31. data/lib/ruby-debug-ide/commands/pause.rb +33 -0
  32. data/lib/ruby-debug-ide/commands/set_type.rb +47 -0
  33. data/lib/ruby-debug-ide/commands/stepping.rb +108 -0
  34. data/lib/ruby-debug-ide/commands/threads.rb +178 -0
  35. data/lib/ruby-debug-ide/commands/variables.rb +154 -0
  36. data/lib/ruby-debug-ide/event_processor.rb +71 -0
  37. data/lib/ruby-debug-ide/greeter.rb +40 -0
  38. data/lib/ruby-debug-ide/helper.rb +33 -0
  39. data/lib/ruby-debug-ide/ide_processor.rb +155 -0
  40. data/lib/ruby-debug-ide/interface.rb +45 -0
  41. data/lib/ruby-debug-ide/multiprocess.rb +23 -0
  42. data/lib/ruby-debug-ide/multiprocess/monkey.rb +47 -0
  43. data/lib/ruby-debug-ide/multiprocess/pre_child.rb +67 -0
  44. data/lib/ruby-debug-ide/multiprocess/starter.rb +11 -0
  45. data/lib/ruby-debug-ide/multiprocess/unmonkey.rb +31 -0
  46. data/lib/ruby-debug-ide/version.rb +3 -0
  47. data/lib/ruby-debug-ide/xml_printer.rb +545 -0
  48. data/ruby-debug-ide-docker.gemspec +51 -0
  49. metadata +110 -0
@@ -0,0 +1,203 @@
1
+ module Debugger
2
+ # Mix-in module to assist in command parsing.
3
+ module EnableDisableFunctions # :nodoc:
4
+ def enable_disable_breakpoints(is_enable, args)
5
+ breakpoints = Debugger.breakpoints.sort_by{|b| b.id }
6
+ largest = breakpoints.inject(0) do |largest_so_far, b|
7
+ b.id if b.id > largest_so_far
8
+ end
9
+ if 0 == largest
10
+ errmsg "No breakpoints have been set.\n"
11
+ return
12
+ end
13
+ args.each do |pos|
14
+ pos = get_int(pos, "#{is_enable} breakpoints", 1, largest)
15
+ return nil unless pos
16
+ breakpoints.each do |b|
17
+ if b.id == pos
18
+ enabled = ("Enable" == is_enable)
19
+ if enabled
20
+ unless syntax_valid?(b.expr)
21
+ errmsg("Expression \"#{b.expr}\" syntactically incorrect; breakpoint remains disabled.\n")
22
+ break
23
+ end
24
+ end
25
+ b.enabled = enabled
26
+ enabled ? print_breakpoint_enabled(b) : print_breakpoint_disabled(b)
27
+ break
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ def enable_disable_display(is_enable, args)
34
+ if 0 == @state.display.size
35
+ errmsg "No display expressions have been set.\n"
36
+ return
37
+ end
38
+ args.each do |pos|
39
+ pos = get_int(pos, "#{is_enable} display", 1, @state.display.size)
40
+ return nil unless pos
41
+ @state.display[pos-1][0] = ("Enable" == is_enable)
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ class EnableCommand < Command # :nodoc:
48
+ Subcommands =
49
+ [
50
+ ['breakpoints', 2, "Enable specified breakpoints",
51
+ "Give breakpoint numbers (separated by spaces) as arguments.
52
+ This is used to cancel the effect of the \"disable\" command."
53
+ ],
54
+ ['display', 2,
55
+ "Enable some expressions to be displayed when program stops",
56
+ "Arguments are the code numbers of the expressions to resume displaying.
57
+ Do \"info display\" to see current list of code numbers."],
58
+ ].map do |name, min, short_help, long_help|
59
+ SubcmdStruct.new(name, min, short_help, long_help)
60
+ end unless defined?(Subcommands)
61
+
62
+ def regexp
63
+ /^\s* en(?:able)? (?:\s+(.*))?$/ix
64
+ end
65
+
66
+ def execute
67
+ if not @match[1]
68
+ errmsg "\"enable\" must be followed \"display\", \"breakpoints\"" +
69
+ " or breakpoint numbers.\n"
70
+ else
71
+ args = @match[1].split(/[ \t]+/)
72
+ param = args.shift
73
+ subcmd = find(Subcommands, param)
74
+ if subcmd
75
+ send("enable_#{subcmd.name}", args)
76
+ else
77
+ send("enable_breakpoints", args.unshift(param))
78
+ end
79
+ end
80
+ end
81
+
82
+ def enable_breakpoints(args)
83
+ enable_disable_breakpoints("Enable", args)
84
+ end
85
+
86
+ def enable_display(args)
87
+ enable_disable_display("Enable", args)
88
+ end
89
+
90
+ class << self
91
+ def help_command
92
+ 'enable'
93
+ end
94
+
95
+ def help(args)
96
+ if args[1]
97
+ s = args[1]
98
+ subcmd = Subcommands.find do |try_subcmd|
99
+ (s.size >= try_subcmd.min) and
100
+ (try_subcmd.name[0..s.size-1] == s)
101
+ end
102
+ if subcmd
103
+ str = subcmd.short_help + '.'
104
+ str += "\n" + subcmd.long_help if subcmd.long_help
105
+ return str
106
+ else
107
+ return "Invalid 'enable' subcommand '#{args[1]}'."
108
+ end
109
+ end
110
+ s = %{
111
+ Enable some things.
112
+ This is used to cancel the effect of the "disable" command.
113
+ --
114
+ List of enable subcommands:
115
+ --
116
+ }
117
+ for subcmd in Subcommands do
118
+ s += "enable #{subcmd.name} -- #{subcmd.short_help}\n"
119
+ end
120
+ return s
121
+ end
122
+ end
123
+ end
124
+
125
+ class DisableCommand < Command # :nodoc:
126
+ Subcommands =
127
+ [
128
+ ['breakpoints', 1, "Disable some breakpoints",
129
+ "Arguments are breakpoint numbers with spaces in between.
130
+ A disabled breakpoint is not forgotten, but has no effect until reenabled."],
131
+ ['display', 1, "Disable some display expressions when program stops",
132
+ "Arguments are the code numbers of the expressions to stop displaying.
133
+ Do \"info display\" to see current list of code numbers."],
134
+ ].map do |name, min, short_help, long_help|
135
+ SubcmdStruct.new(name, min, short_help, long_help)
136
+ end unless defined?(Subcommands)
137
+
138
+ def regexp
139
+ /^\s* dis(?:able)? (?:\s+(.*))?$/ix
140
+ end
141
+
142
+ def execute
143
+ if not @match[1]
144
+ errmsg "\"disable\" must be followed \"display\", \"breakpoints\"" +
145
+ " or breakpoint numbers.\n"
146
+ else
147
+ args = @match[1].split(/[ \t]+/)
148
+ param = args.shift
149
+ subcmd = find(Subcommands, param)
150
+ if subcmd
151
+ send("disable_#{subcmd.name}", args)
152
+ else
153
+ send("disable_breakpoints", args.unshift(param))
154
+ end
155
+ end
156
+ end
157
+
158
+ def disable_breakpoints(args)
159
+ enable_disable_breakpoints("Disable", args)
160
+ end
161
+
162
+ def disable_display(args)
163
+ enable_disable_display("Disable", args)
164
+ end
165
+
166
+ class << self
167
+ def help_command
168
+ 'disable'
169
+ end
170
+
171
+ def help(args)
172
+ if args[1]
173
+ s = args[1]
174
+ subcmd = Subcommands.find do |try_subcmd|
175
+ (s.size >= try_subcmd.min) and
176
+ (try_subcmd.name[0..s.size-1] == s)
177
+ end
178
+ if subcmd
179
+ str = subcmd.short_help + '.'
180
+ str += "\n" + subcmd.long_help if subcmd.long_help
181
+ return str
182
+ else
183
+ return "Invalid 'disable' subcommand '#{args[1]}'."
184
+ end
185
+ end
186
+ s = %{
187
+ Disable some things.
188
+
189
+ A disabled item is not forgotten, but has no effect until reenabled.
190
+ Use the "enable" command to have it take effect again.
191
+ --
192
+ List of disable subcommands:
193
+ --
194
+ }
195
+ for subcmd in Subcommands do
196
+ s += "disable #{subcmd.name} -- #{subcmd.short_help}\n"
197
+ end
198
+ return s
199
+ end
200
+ end
201
+ end
202
+
203
+ end # module Debugger
@@ -0,0 +1,64 @@
1
+ module Debugger
2
+ class EvalCommand < Command # :nodoc:
3
+ #self.control = true
4
+
5
+ def match(input)
6
+ @input = input
7
+ super
8
+ end
9
+
10
+ def regexp
11
+ /^\s*(p|e(?:val)?)\s+/
12
+ end
13
+
14
+ def execute
15
+ expr = @match ? @match.post_match : @input
16
+ binding = @state.context ? get_binding : TOPLEVEL_BINDING
17
+ print_eval expr, debug_eval(expr, binding).inspect
18
+ end
19
+
20
+ class << self
21
+ def help_command
22
+ %w|p eval|
23
+ end
24
+
25
+ def help(cmd)
26
+ if cmd == 'p'
27
+ %{
28
+ p expression\tevaluate expression and print its value
29
+ }
30
+ else
31
+ %{
32
+ e[val] expression\tevaluate expression and print its value,
33
+ \t\t\talias for p.
34
+ }
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ class PPCommand < Command # :nodoc:
41
+ def regexp
42
+ /^\s*pp\s+/
43
+ end
44
+
45
+ def execute
46
+ exp = @match.post_match
47
+ out = StringIO.new
48
+ PP.pp(debug_eval(exp), out) rescue out.puts $!.message
49
+ print_pp out.string
50
+ end
51
+
52
+ class << self
53
+ def help_command
54
+ 'pp'
55
+ end
56
+
57
+ def help(cmd)
58
+ %{
59
+ pp expression\tevaluate expression and print its value
60
+ }
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,71 @@
1
+ require 'stringio'
2
+ require 'irb/ruby-lex'
3
+
4
+ module Debugger
5
+
6
+ class ExpressionInfoCommand < Command
7
+ def regexp
8
+ /^\s*ex(?:pression_info)?\s+/
9
+ end
10
+
11
+ def execute
12
+ string_to_parse = Command.unescape_incoming(@match.post_match) + " \n \n\n"
13
+ total_lines = string_to_parse.count("\n") + 1
14
+
15
+ lexer = RubyLex.new
16
+ lexer.set_input(create_io_reader(string_to_parse))
17
+
18
+ last_statement = ''
19
+ last_prompt = ''
20
+ last_indent = 0
21
+ lexer.set_prompt do |ltype, indent, continue, lineno|
22
+ next if (lineno >= total_lines)
23
+
24
+ last_prompt = ltype || ''
25
+ last_indent = indent
26
+ end
27
+
28
+ lexer.each_top_level_statement do |line, line_no|
29
+ last_statement = line
30
+ end
31
+
32
+ incomplete = true
33
+ if /\A\s*\Z/m =~ last_statement
34
+ incomplete = false
35
+ end
36
+
37
+ @printer.print_expression_info(incomplete, last_prompt, last_indent)
38
+ end
39
+
40
+ def create_io_reader(string_to_parse)
41
+ io = StringIO.new(string_to_parse)
42
+
43
+ if string_to_parse.respond_to?(:encoding)
44
+ io.instance_exec(string_to_parse.encoding) do |string_encoding|
45
+ @my_encoding = string_encoding
46
+ def self.encoding
47
+ @my_encoding
48
+ end
49
+ end
50
+ end
51
+
52
+ io
53
+ end
54
+
55
+ class << self
56
+ def help_command
57
+ "expression_info"
58
+ end
59
+
60
+ def help(cmd)
61
+ %{
62
+ ex[pression_info] <expression>\t
63
+ returns parser-related information for the expression given\t\t
64
+ 'incomplete'=true|false\tindicates whether expression is a complete ruby
65
+ expression and can be evaluated without getting syntax errors
66
+ }
67
+ end
68
+ end
69
+ end
70
+
71
+ end
@@ -0,0 +1,107 @@
1
+ module Debugger
2
+ class IncludeFile < Command # :nodoc:
3
+ self.control = true
4
+
5
+ def regexp
6
+ / ^\s*include\s+(.+?)\s*$/x
7
+ end
8
+
9
+ def execute
10
+ file = @match[1]
11
+
12
+ return if file.nil?
13
+ file = realpath(file)
14
+
15
+ if Command.file_filter_supported?
16
+ Debugger.file_filter.include(file)
17
+ print_file_included(file)
18
+ else
19
+ print_debug("file filter is not supported")
20
+ end
21
+ end
22
+
23
+ class << self
24
+ def help_command
25
+ 'include'
26
+ end
27
+
28
+ def help(cmd)
29
+ %{
30
+ include file - adds file/dir to file filter (either remove already excluded or add as included)
31
+ }
32
+ end
33
+ end
34
+ end
35
+
36
+ class ExcludeFile < Command # :nodoc:
37
+ self.control = true
38
+
39
+ def regexp
40
+ / ^\s*exclude\s+(.+?)\s*$/x
41
+ end
42
+
43
+ def execute
44
+ file = @match[1]
45
+
46
+ return if file.nil?
47
+ file = realpath(file)
48
+
49
+ if Command.file_filter_supported?
50
+ Debugger.file_filter.exclude(file)
51
+ print_file_excluded(file)
52
+ else
53
+ print_debug("file filter is not supported")
54
+ end
55
+ end
56
+
57
+ class << self
58
+ def help_command
59
+ 'include'
60
+ end
61
+
62
+ def help(cmd)
63
+ %{
64
+ exclude file - exclude file/dir from file filter (either remove already included or add as exclude)
65
+ }
66
+ end
67
+ end
68
+ end
69
+
70
+ class FileFilterCommand < Command # :nodoc:
71
+ self.control = true
72
+
73
+ def regexp
74
+ / ^\s*file-filter\s+(on|off)\s*$/x
75
+ end
76
+
77
+ def execute
78
+ action = @match[1]
79
+
80
+ if Command.file_filter_supported?
81
+ if 'on' == action
82
+ Debugger.file_filter.enable
83
+ print_file_filter_status(true)
84
+ elsif 'off' == action
85
+ Debugger.file_filter.disable
86
+ print_file_filter_status(false)
87
+ else
88
+ print_error "Unknown option '#{action}'"
89
+ end
90
+ else
91
+ print_debug("file filter is not supported")
92
+ end
93
+ end
94
+
95
+ class << self
96
+ def help_command
97
+ 'file-filter'
98
+ end
99
+
100
+ def help(cmd)
101
+ %{
102
+ file-filter (on|off) - enable/disable file filtering
103
+ }
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,155 @@
1
+ module Debugger
2
+
3
+ module FrameFunctions # :nodoc:
4
+
5
+ def adjust_frame(frame_pos, absolute)
6
+ if absolute
7
+ if frame_pos < 0
8
+ abs_frame_pos = @state.context.stack_size + frame_pos
9
+ else
10
+ abs_frame_pos = frame_pos - 1
11
+ end
12
+ else
13
+ abs_frame_pos = @state.frame_pos + frame_pos
14
+ end
15
+
16
+ if abs_frame_pos >= @state.context.stack_size then
17
+ print_error "Adjusting would put us beyond the oldest (initial) frame.\n"
18
+ return
19
+ elsif abs_frame_pos < 0 then
20
+ print_error "Adjusting would put us beyond the newest (innermost) frame.\n"
21
+ return
22
+ end
23
+ if @state.frame_pos != abs_frame_pos then
24
+ @state.previous_line = nil
25
+ @state.frame_pos = abs_frame_pos
26
+ end
27
+ @state.file = @state.context.frame_file(@state.frame_pos)
28
+ @state.line = @state.context.frame_line(@state.frame_pos)
29
+
30
+ print_current_frame(@state.frame_pos)
31
+ end
32
+
33
+ end
34
+
35
+ class WhereCommand < Command # :nodoc:
36
+ def regexp
37
+ /^\s*(?:w(?:here)?|bt|backtrace)$/
38
+ end
39
+
40
+ def execute
41
+ print_frames(@state.context, @state.frame_pos)
42
+ end
43
+
44
+ class << self
45
+ def help_command
46
+ %w|where backtrace|
47
+ end
48
+
49
+ def help(cmd)
50
+ if cmd == 'where'
51
+ %{
52
+ w[here]\tdisplay frames
53
+ }
54
+ else
55
+ %{
56
+ bt|backtrace\t\talias for where
57
+ }
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ class UpCommand < Command # :nodoc:
64
+ include FrameFunctions
65
+ def regexp
66
+ /^\s* u(?:p)? (?:\s+(.*))? .*$/x
67
+ end
68
+
69
+ def execute
70
+ unless @match[1]
71
+ pos = 1
72
+ else
73
+ pos = get_int(@match[1], "Up")
74
+ return unless pos
75
+ end
76
+ adjust_frame(pos, false)
77
+ end
78
+
79
+ class << self
80
+ def help_command
81
+ 'up'
82
+ end
83
+
84
+ def help(cmd)
85
+ %{
86
+ up[count]\tmove to higher frame
87
+ }
88
+ end
89
+ end
90
+ end
91
+
92
+ class DownCommand < Command # :nodoc:
93
+ include FrameFunctions
94
+ def regexp
95
+ /^\s* down (?:\s+(.*))? .*$/x
96
+ end
97
+
98
+ def execute
99
+ if not @match[1]
100
+ pos = 1
101
+ else
102
+ pos = get_int(@match[1], "Down")
103
+ return unless pos
104
+ end
105
+ adjust_frame(-pos, false)
106
+ end
107
+
108
+ class << self
109
+ def help_command
110
+ 'down'
111
+ end
112
+
113
+ def help(cmd)
114
+ %{
115
+ down[count]\tmove to lower frame
116
+ }
117
+ end
118
+ end
119
+ end
120
+
121
+ class FrameCommand < Command # :nodoc:
122
+ include FrameFunctions
123
+ def regexp
124
+ /^\s* f(?:rame)? (?:\s+ (.*))? \s*$/x
125
+ end
126
+
127
+ def execute
128
+ if not @match[1]
129
+ print "Missing a frame number argument.\n"
130
+ return
131
+ else
132
+ pos = get_int(@match[1], "Frame")
133
+ return unless pos
134
+ end
135
+ adjust_frame(pos, true)
136
+ end
137
+
138
+ class << self
139
+ def help_command
140
+ 'frame'
141
+ end
142
+
143
+ def help(cmd)
144
+ %{
145
+ f[rame] frame-number
146
+ Move the current frame to the specified frame number.
147
+
148
+ A negative number indicates position from the other end. So
149
+ 'frame -1' moves to the oldest frame, and 'frame 0' moves to
150
+ the newest frame.
151
+ }
152
+ end
153
+ end
154
+ end
155
+ end