ruby-debug-ide19 0.4.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/CHANGES +75 -0
  2. data/ChangeLog +465 -0
  3. data/ChangeLog.archive +1073 -0
  4. data/MIT-LICENSE +24 -0
  5. data/Rakefile +110 -0
  6. data/bin/rdebug-ide +88 -0
  7. data/ext/mkrf_conf.rb +28 -0
  8. data/lib/ruby-debug-ide.rb +172 -0
  9. data/lib/ruby-debug/command.rb +169 -0
  10. data/lib/ruby-debug/commands/breakpoints.rb +129 -0
  11. data/lib/ruby-debug/commands/catchpoint.rb +52 -0
  12. data/lib/ruby-debug/commands/condition.rb +51 -0
  13. data/lib/ruby-debug/commands/control.rb +129 -0
  14. data/lib/ruby-debug/commands/enable.rb +203 -0
  15. data/lib/ruby-debug/commands/eval.rb +64 -0
  16. data/lib/ruby-debug/commands/frame.rb +155 -0
  17. data/lib/ruby-debug/commands/inspect.rb +24 -0
  18. data/lib/ruby-debug/commands/jump.rb +73 -0
  19. data/lib/ruby-debug/commands/load.rb +18 -0
  20. data/lib/ruby-debug/commands/stepping.rb +108 -0
  21. data/lib/ruby-debug/commands/threads.rb +153 -0
  22. data/lib/ruby-debug/commands/variables.rb +136 -0
  23. data/lib/ruby-debug/event_processor.rb +74 -0
  24. data/lib/ruby-debug/helper.rb +33 -0
  25. data/lib/ruby-debug/interface.rb +39 -0
  26. data/lib/ruby-debug/printers.rb +2 -0
  27. data/lib/ruby-debug/processor.rb +152 -0
  28. data/lib/ruby-debug/xml_printer.rb +268 -0
  29. data/test/rd_basic_test.rb +10 -0
  30. data/test/rd_catchpoint_test.rb +20 -0
  31. data/test/rd_condition_test.rb +11 -0
  32. data/test/rd_enable_disable_test.rb +43 -0
  33. data/test/rd_inspect_test.rb +11 -0
  34. data/test/rd_stepping_breakpoints_test.rb +36 -0
  35. data/test/rd_test_base.rb +44 -0
  36. data/test/rd_threads_and_frames_test.rb +11 -0
  37. data/test/rd_variables_test.rb +11 -0
  38. data/test/ruby-debug/xml_printer_test.rb +105 -0
  39. metadata +103 -0
@@ -0,0 +1,129 @@
1
+ module Debugger
2
+ class AddBreakpoint < Command # :nodoc:
3
+ self.control = true
4
+
5
+ def regexp
6
+ / ^\s*
7
+ b(?:reak)?
8
+ (?: \s+
9
+ (?:
10
+ (\d+) |
11
+ (.+?)[:.#]([^.:\s]+)
12
+ ))?
13
+ (?:\s+
14
+ if\s+(.+)
15
+ )?
16
+ $
17
+ /x
18
+ end
19
+
20
+ def execute
21
+ if @match[1]
22
+ line, _, _, expr = @match.captures
23
+ else
24
+ _, file, line, expr = @match.captures
25
+ end
26
+
27
+ if file.nil?
28
+ file = File.basename(@state.file)
29
+ else
30
+ if line !~ /^\d+$/
31
+ klass = debug_silent_eval(file)
32
+ if klass && !klass.kind_of?(Module)
33
+ print_error "Unknown class #{file}"
34
+ throw :debug_error
35
+ end
36
+ file = klass.name if klass
37
+ else
38
+ file = File.expand_path(file) if file.index(File::SEPARATOR) || \
39
+ File::ALT_SEPARATOR && file.index(File::ALT_SEPARATOR)
40
+ end
41
+ end
42
+
43
+ if line =~ /^\d+$/
44
+ line = line.to_i
45
+ else
46
+ line = line.intern.id2name
47
+ end
48
+
49
+ b = Debugger.add_breakpoint file, line, expr
50
+ print_breakpoint_added b
51
+ end
52
+
53
+ class << self
54
+ def help_command
55
+ 'break'
56
+ end
57
+
58
+ def help(cmd)
59
+ %{
60
+ b[reak] file:line [if expr]
61
+ b[reak] [file|class(:|.|#)]<line|method> [if expr] -
62
+ \tset breakpoint to some position, (optionally) if expr == true
63
+ }
64
+ end
65
+ end
66
+ end
67
+
68
+ class BreakpointsCommand < Command # :nodoc:
69
+ self.control = true
70
+
71
+ def regexp
72
+ /^\s*b(?:reak)?$/
73
+ end
74
+
75
+ def execute
76
+ print_breakpoints Debugger.breakpoints
77
+ end
78
+
79
+ class << self
80
+ def help_command
81
+ 'break'
82
+ end
83
+
84
+ def help(cmd)
85
+ %{
86
+ b[reak]\tlist breakpoints
87
+ }
88
+ end
89
+ end
90
+ end
91
+
92
+ class DeleteBreakpointCommand < Command # :nodoc:
93
+ self.control = true
94
+
95
+ def regexp
96
+ /^\s*del(?:ete)?(?:\s+(.*))?$/
97
+ end
98
+
99
+ def execute
100
+ brkpts = @match[1]
101
+ unless brkpts
102
+ Debugger.breakpoints.clear
103
+ else
104
+ brkpts.split(/[ \t]+/).each do |pos|
105
+ pos = get_int(pos, "Delete", 1)
106
+ return unless pos
107
+ b = Debugger.remove_breakpoint(pos)
108
+ if b
109
+ print_breakpoint_deleted b
110
+ else
111
+ print_error "No breakpoint number %d\n", pos
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ class << self
118
+ def help_command
119
+ 'delete'
120
+ end
121
+
122
+ def help(cmd)
123
+ %{
124
+ del[ete][ nnn...]\tdelete some or all breakpoints
125
+ }
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,52 @@
1
+ module Debugger
2
+ class CatchCommand < Command # :nodoc:
3
+ self.control = true
4
+
5
+ def regexp
6
+ /^\s* cat(?:ch)?
7
+ (?:\s+ (\S+))?
8
+ (?:\s+ (off))? \s* $/ix
9
+ end
10
+
11
+ def execute
12
+ excn = @match[1]
13
+ if not excn
14
+ # No args given.
15
+ errmsg "Exception class must be specified for 'catch' command"
16
+ elsif not @match[2]
17
+ # One arg given.
18
+ if 'off' == excn
19
+ Debugger.catchpoints.clear
20
+ else
21
+ binding = @state.context ? get_binding : TOPLEVEL_BINDING
22
+ unless debug_eval("#{excn}.is_a?(Class)", binding)
23
+ print_msg "Warning #{excn} is not known to be a Class"
24
+ end
25
+ Debugger.add_catchpoint(excn)
26
+ print_catchpoint_set(excn)
27
+ end
28
+ elsif @match[2] != 'off'
29
+ errmsg "Off expected. Got %s\n", @match[2]
30
+ elsif Debugger.catchpoints.member?(excn)
31
+ Debugger.catchpoints.delete(excn)
32
+ print_catchpoint_set(excn)
33
+ #print "Catch for exception %s removed.\n", excn
34
+ else
35
+ errmsg "Catch for exception %s not found.\n", excn
36
+ end
37
+ end
38
+
39
+ class << self
40
+ def help_command
41
+ 'catch'
42
+ end
43
+
44
+ def help(cmd)
45
+ %{
46
+ cat[ch]\t\t\tshow catchpoint
47
+ cat[ch] <an Exception>\tset catchpoint to an exception
48
+ }
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,51 @@
1
+ module Debugger
2
+
3
+ class ConditionCommand < Command # :nodoc:
4
+ self.control = true
5
+
6
+ def regexp
7
+ /^\s* cond(?:ition)? (?:\s+(\d+)\s*(.*))?$/ix
8
+ end
9
+
10
+ def execute
11
+ if not @match[1]
12
+ errmsg "\"condition\" must be followed a breakpoint number and expression\n"
13
+ else
14
+ breakpoints = Debugger.breakpoints.sort_by{|b| b.id }
15
+ largest = breakpoints.inject(0) do |largest, b|
16
+ largest = b.id if b.id > largest
17
+ end
18
+ if 0 == largest
19
+ print "No breakpoints have been set.\n"
20
+ return
21
+ end
22
+ pos = get_int(@match[1], "Condition", 1, largest)
23
+ return unless pos
24
+ breakpoints.each do |b|
25
+ if b.id == pos
26
+ b.expr = @match[2].empty? ? nil : @match[2]
27
+ print_contdition_set(b.id)
28
+ break
29
+ end
30
+ end
31
+
32
+ end
33
+ end
34
+
35
+ class << self
36
+ def help_command
37
+ 'condition'
38
+ end
39
+
40
+ def help(cmd)
41
+ %{
42
+ Condition breakpoint-number expression
43
+ Specify breakpoint number N to break only if COND is true.
44
+ N is an integer and COND is an expression to be evaluated whenever
45
+ breakpoint N is reached. If the empty string is used, the condition is removed.
46
+ }
47
+ end
48
+ end
49
+ end
50
+
51
+ end # module Debugger
@@ -0,0 +1,129 @@
1
+ module Debugger
2
+ class QuitCommand < Command # :nodoc:
3
+ self.control = true
4
+
5
+ def regexp
6
+ /^\s*(?:q(?:uit)?|exit)\s*$/
7
+ end
8
+
9
+ def execute
10
+ begin
11
+ @printer.print_msg("finished")
12
+ @printer.print_debug("Exiting debugger.")
13
+ ensure
14
+ exit! # exit -> exit!: No graceful way to stop threads...
15
+ end
16
+ end
17
+
18
+ class << self
19
+ def help_command
20
+ %w[quit exit]
21
+ end
22
+
23
+ def help(cmd)
24
+ %{
25
+ q[uit]\texit from debugger,
26
+ exit\talias to quit
27
+ }
28
+ end
29
+ end
30
+ end
31
+
32
+ class RestartCommand < Command # :nodoc:
33
+ self.control = true
34
+
35
+ def regexp
36
+ / ^\s*
37
+ (restart|R)
38
+ (\s+ \S+ .*)?
39
+ $
40
+ /x
41
+ end
42
+
43
+ def execute
44
+ if not defined? Debugger::RDEBUG_SCRIPT or not defined? Debugger::ARGV
45
+ print "We are not in a context we can restart from.\n"
46
+ return
47
+ end
48
+ if @match[2]
49
+ args = Debugger::PROG_SCRIPT + " " + @match[2]
50
+ else
51
+ args = Debugger::ARGV.join(" ")
52
+ end
53
+
54
+ # An execv would be preferable to the "exec" below.
55
+ cmd = Debugger::RDEBUG_SCRIPT + " " + args
56
+ print "Re exec'ing:\n\t#{cmd}\n"
57
+ exec cmd
58
+ end
59
+
60
+ class << self
61
+ def help_command
62
+ 'restart'
63
+ end
64
+
65
+ def help(cmd)
66
+ %{
67
+ restart|R [args]
68
+ Restart the program. This is is a re-exec - all debugger state
69
+ is lost. If command arguments are passed those are used.
70
+ }
71
+ end
72
+ end
73
+ end
74
+
75
+ class StartCommand < Command # :nodoc:
76
+ self.control = true
77
+
78
+ def regexp
79
+ /^\s*(start)(\s+ \S+ .*)?$/x
80
+ end
81
+
82
+ def execute
83
+ @printer.print_debug("Starting: running program script")
84
+ Debugger.run_prog_script #Debugger.prog_script_running?
85
+ end
86
+
87
+ class << self
88
+ def help_command
89
+ 'start'
90
+ end
91
+
92
+ def help(cmd)
93
+ %{
94
+ run prog script
95
+ }
96
+ end
97
+ end
98
+ end
99
+
100
+
101
+ class InterruptCommand < Command # :nodoc:
102
+ self.event = false
103
+ self.control = true
104
+ self.need_context = true
105
+
106
+ def regexp
107
+ /^\s*i(?:nterrupt)?\s*$/
108
+ end
109
+
110
+ def execute
111
+ unless Debugger.interrupt_last
112
+ context = Debugger.thread_context(Thread.main)
113
+ context.interrupt
114
+ end
115
+ end
116
+
117
+ class << self
118
+ def help_command
119
+ 'interrupt'
120
+ end
121
+
122
+ def help(cmd)
123
+ %{
124
+ i[nterrupt]\tinterrupt the program
125
+ }
126
+ end
127
+ end
128
+ end
129
+ end
@@ -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, b|
7
+ largest = b.id if b.id > largest
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