ruby-debug-ide22 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) 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 +38 -0
  6. data/MIT-LICENSE +24 -0
  7. data/Rakefile +93 -0
  8. data/bin/gdb_wrapper +96 -0
  9. data/bin/rdebug-ide +200 -0
  10. data/ext/mkrf_conf.rb +44 -0
  11. data/lib/ruby-debug-ide/attach/debugger_loader.rb +20 -0
  12. data/lib/ruby-debug-ide/attach/gdb.rb +73 -0
  13. data/lib/ruby-debug-ide/attach/lldb.rb +71 -0
  14. data/lib/ruby-debug-ide/attach/native_debugger.rb +133 -0
  15. data/lib/ruby-debug-ide/attach/process_thread.rb +54 -0
  16. data/lib/ruby-debug-ide/attach/util.rb +115 -0
  17. data/lib/ruby-debug-ide/command.rb +187 -0
  18. data/lib/ruby-debug-ide/commands/breakpoints.rb +128 -0
  19. data/lib/ruby-debug-ide/commands/catchpoint.rb +64 -0
  20. data/lib/ruby-debug-ide/commands/condition.rb +51 -0
  21. data/lib/ruby-debug-ide/commands/control.rb +158 -0
  22. data/lib/ruby-debug-ide/commands/enable.rb +203 -0
  23. data/lib/ruby-debug-ide/commands/eval.rb +64 -0
  24. data/lib/ruby-debug-ide/commands/expression_info.rb +71 -0
  25. data/lib/ruby-debug-ide/commands/file_filtering.rb +107 -0
  26. data/lib/ruby-debug-ide/commands/frame.rb +155 -0
  27. data/lib/ruby-debug-ide/commands/inspect.rb +25 -0
  28. data/lib/ruby-debug-ide/commands/jump.rb +73 -0
  29. data/lib/ruby-debug-ide/commands/load.rb +18 -0
  30. data/lib/ruby-debug-ide/commands/pause.rb +33 -0
  31. data/lib/ruby-debug-ide/commands/set_type.rb +47 -0
  32. data/lib/ruby-debug-ide/commands/stepping.rb +108 -0
  33. data/lib/ruby-debug-ide/commands/threads.rb +178 -0
  34. data/lib/ruby-debug-ide/commands/variables.rb +154 -0
  35. data/lib/ruby-debug-ide/event_processor.rb +71 -0
  36. data/lib/ruby-debug-ide/greeter.rb +42 -0
  37. data/lib/ruby-debug-ide/helper.rb +33 -0
  38. data/lib/ruby-debug-ide/ide_processor.rb +155 -0
  39. data/lib/ruby-debug-ide/interface.rb +45 -0
  40. data/lib/ruby-debug-ide/multiprocess/monkey.rb +47 -0
  41. data/lib/ruby-debug-ide/multiprocess/pre_child.rb +59 -0
  42. data/lib/ruby-debug-ide/multiprocess/starter.rb +11 -0
  43. data/lib/ruby-debug-ide/multiprocess/unmonkey.rb +31 -0
  44. data/lib/ruby-debug-ide/multiprocess.rb +23 -0
  45. data/lib/ruby-debug-ide/thread_alias.rb +27 -0
  46. data/lib/ruby-debug-ide/version.rb +3 -0
  47. data/lib/ruby-debug-ide/xml_printer.rb +571 -0
  48. data/lib/ruby-debug-ide.rb +228 -0
  49. data/ruby-debug-ide.gemspec +47 -0
  50. metadata +110 -0
@@ -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
@@ -0,0 +1,25 @@
1
+ module Debugger
2
+
3
+ class InspectCommand < Command
4
+ # reference inspection results in order to save them from the GC
5
+ @@references = []
6
+ def self.reference_result(result)
7
+ @@references << result
8
+ end
9
+ def self.clear_references
10
+ @@references = []
11
+ end
12
+
13
+ def regexp
14
+ /^\s*v(?:ar)?\s+inspect\s+/
15
+ end
16
+ #
17
+ def execute
18
+ binding = @state.context ? get_binding : TOPLEVEL_BINDING
19
+ obj = debug_eval(@match.post_match, binding)
20
+ InspectCommand.reference_result(obj)
21
+ @printer.print_inspect(obj)
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,73 @@
1
+ module Debugger
2
+
3
+ # Implements debugger "jump" command
4
+ class JumpCommand < Command
5
+ self.need_context = true
6
+
7
+ def numeric?(object)
8
+ true if Float(object) rescue false
9
+ end
10
+
11
+ def regexp
12
+ / ^\s*
13
+ j(?:ump)? \s*
14
+ (?:\s+(\S+))?\s*
15
+ (?:\s+(\S+))?\s*
16
+ $
17
+ /ix
18
+ end
19
+
20
+ def execute
21
+ unless @state.context.respond_to?(:jump)
22
+ print_msg "Not implemented"
23
+ return
24
+ end
25
+ if !@match[1]
26
+ print_msg "\"jump\" must be followed by a line number"
27
+ return
28
+ end
29
+ if !numeric?(@match[1])
30
+ print_msg "Bad line number: " + @match[1]
31
+ return
32
+ end
33
+ line = @match[1].to_i
34
+ line = @state.context.frame_line(0) + line if @match[1][0] == '+' or @match[1][0] == '-'
35
+ if line == @state.context.frame_line(0)
36
+ return
37
+ end
38
+ file = @match[2]
39
+ file = @state.context.frame_file(file.to_i) if numeric?(file)
40
+ file = @state.context.frame_file(0) if !file
41
+ case @state.context.jump(line, file)
42
+ when 0
43
+ @state.proceed
44
+ return
45
+ when 1
46
+ print_msg "Not possible to jump from here"
47
+ when 2
48
+ print_msg "Couldn't find debugged frame"
49
+ when 3
50
+ print_msg "Couldn't find active code at " + file + ":" + line.to_s
51
+ else
52
+ print_msg "Unknown error occurred"
53
+ end
54
+ @printer.print_at_line(@state.context, @state.context.frame_file, @state.context.frame_line)
55
+ end
56
+
57
+ class << self
58
+ def help_command
59
+ %w[jump]
60
+ end
61
+
62
+ def help(cmd)
63
+ %{
64
+ j[ump] line\tjump to line number (absolute)
65
+ j[ump] -line\tjump back to line (relative)
66
+ j[ump] +line\tjump ahead to line (relative)
67
+
68
+ Change the next line of code to be executed.
69
+ }
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,18 @@
1
+ module Debugger
2
+ class LoadCommand < Command
3
+ def regexp
4
+ /^\s*load\s+/
5
+ end
6
+
7
+ def execute
8
+ fileName = @match.post_match
9
+ @printer.print_debug("loading file: %s", fileName)
10
+ begin
11
+ load fileName
12
+ @printer.print_load_result(fileName)
13
+ rescue Exception => error
14
+ @printer.print_load_result(fileName, error)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,33 @@
1
+ module Debugger
2
+
3
+ # Implements debugger "pause" command
4
+ class PauseCommand < Command
5
+ self.control = true
6
+
7
+ def regexp
8
+ /^\s*pause\s*(?:\s+(\S+))?\s*$/
9
+ end
10
+
11
+ def execute
12
+ Debugger.contexts.each do |c|
13
+ unless c.respond_to?(:pause)
14
+ print_msg "Not implemented"
15
+ return
16
+ end
17
+ c.pause
18
+ end
19
+ end
20
+
21
+ class << self
22
+ def help_command
23
+ %w[pause]
24
+ end
25
+
26
+ def help(cmd)
27
+ %{
28
+ pause <nnn>\tpause a running thread
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,47 @@
1
+ module Debugger
2
+
3
+ # Implements debugger "set_type" command
4
+ class SetTypeCommand < Command
5
+ self.need_context = true
6
+
7
+ def regexp
8
+ / ^\s*
9
+ set_type? \s*
10
+ (?:\s+(\S+))?\s*
11
+ (?:\s+(\S+))?\s*
12
+ $
13
+ /ix
14
+ end
15
+
16
+ def execute
17
+ if RUBY_VERSION < "1.9"
18
+ print_msg "Not implemented"
19
+ return
20
+ end
21
+ begin
22
+ expr = @match[1] + " = " + @match[2] + "(" + @match[1] + ".inspect)"
23
+ eval(expr)
24
+ rescue
25
+ begin
26
+ expr = @match[1] + " = " + @match[2] + ".new(" + @match[1] + ".inspect)"
27
+ eval(expr)
28
+ rescue nil
29
+ end
30
+ end
31
+ end
32
+
33
+ class << self
34
+ def help_command
35
+ %w[set_type]
36
+ end
37
+
38
+ def help(cmd)
39
+ %{
40
+ set_type <var> <type>
41
+
42
+ Change the type of <var> to <type>
43
+ }
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,108 @@
1
+ module Debugger
2
+ class NextCommand < Command # :nodoc:
3
+ self.need_context = true
4
+
5
+ def regexp
6
+ /^\s*n(?:ext)?([+-])?(?:\s+(\d+))?$/
7
+ end
8
+
9
+ def execute
10
+ force = @match[1] == '+'
11
+ steps = @match[2] ? @match[2].to_i : 1
12
+ @state.context.step_over steps, @state.frame_pos, force
13
+ @state.proceed
14
+ end
15
+
16
+ class << self
17
+ def help_command
18
+ 'next'
19
+ end
20
+
21
+ def help(cmd)
22
+ %{
23
+ n[ext][+][ nnn]\tstep over once or nnn times,
24
+ \t\t'+' forces to move to another line
25
+ }
26
+ end
27
+ end
28
+ end
29
+
30
+ class StepCommand < Command # :nodoc:
31
+ self.need_context = true
32
+
33
+ def regexp
34
+ /^\s*s(?:tep)?([+-])?(?:\s+(\d+))?$/
35
+ end
36
+
37
+ def execute
38
+ force = @match[1] == '+'
39
+ steps = @match[2] ? @match[2].to_i : 1
40
+ @state.context.step(steps, force)
41
+ @state.proceed
42
+ end
43
+
44
+ class << self
45
+ def help_command
46
+ 'step'
47
+ end
48
+
49
+ def help(cmd)
50
+ %{
51
+ s[tep][ nnn]\tstep (into methods) once or nnn times
52
+ }
53
+ end
54
+ end
55
+ end
56
+
57
+ class FinishCommand < Command # :nodoc:
58
+ self.need_context = true
59
+
60
+ def regexp
61
+ /^\s*fin(?:ish)?$/
62
+ end
63
+
64
+ def execute
65
+ if @state.frame_pos == @state.context.stack_size - 1
66
+ print_msg "\"finish\" not meaningful in the outermost frame."
67
+ else
68
+ @state.context.stop_frame = @state.frame_pos
69
+ @state.frame_pos = 0
70
+ @state.proceed
71
+ end
72
+ end
73
+
74
+ class << self
75
+ def help_command
76
+ 'finish'
77
+ end
78
+
79
+ def help(cmd)
80
+ %{
81
+ fin[ish]\treturn to outer frame
82
+ }
83
+ end
84
+ end
85
+ end
86
+
87
+ class ContinueCommand < Command # :nodoc:
88
+ def regexp
89
+ /^\s*c(?:ont)?$/
90
+ end
91
+
92
+ def execute
93
+ @state.proceed
94
+ end
95
+
96
+ class << self
97
+ def help_command
98
+ 'cont'
99
+ end
100
+
101
+ def help(cmd)
102
+ %{
103
+ c[ont]\trun until program ends or hit breakpoint
104
+ }
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,178 @@
1
+ module Debugger
2
+ class ThreadListCommand < Command # :nodoc:
3
+ self.control = true
4
+ def regexp
5
+ /^\s*th(?:read)?\s+l(?:ist)?\s*$/
6
+ end
7
+
8
+ def execute
9
+ contexts = Debugger.contexts.sort_by{|c| c.thnum}
10
+ print_contexts(contexts)
11
+ end
12
+
13
+ class << self
14
+ def help_command
15
+ 'thread'
16
+ end
17
+
18
+ def help(cmd)
19
+ %{
20
+ th[read] l[ist]\t\t\tlist all threads
21
+ }
22
+ end
23
+ end
24
+ end
25
+
26
+ class ThreadSwitchCommand < Command # :nodoc:
27
+ self.control = true
28
+ self.need_context = true
29
+
30
+ def regexp
31
+ /^\s*th(?:read)?\s+(?:sw(?:itch)?\s+)?(\d+)\s*$/
32
+ end
33
+
34
+ def execute
35
+ c = get_context(@match[1].to_i)
36
+ case
37
+ when c == @state.context
38
+ print_msg "It's the current thread."
39
+ when c.ignored?
40
+ print_msg "Can't switch to the debugger thread."
41
+ else
42
+ print_context(c)
43
+ c.stop_next = 1
44
+ c.thread.run
45
+ @state.proceed
46
+ end
47
+ end
48
+
49
+ class << self
50
+ def help_command
51
+ 'thread'
52
+ end
53
+
54
+ def help(cmd)
55
+ %{
56
+ th[read] [sw[itch]] <nnn>\tswitch thread context to nnn
57
+ }
58
+ end
59
+ end
60
+ end
61
+
62
+ class ThreadInspectCommand < Command # :nodoc:
63
+ self.control = true
64
+ self.need_context = true
65
+
66
+ def regexp
67
+ /^\s*th(?:read)?\s+in(?:spect)?\s+(\d+)\s*$/
68
+ end
69
+
70
+ def execute
71
+ @state.context = get_context(@match[1].to_i)
72
+ end
73
+
74
+ class << self
75
+ def help_command
76
+ 'thread'
77
+ end
78
+
79
+ def help(cmd)
80
+ %{
81
+ th[read] in[spect] <nnn>\tswitch thread context to nnn but don't resume any threads
82
+ }
83
+ end
84
+ end
85
+ end
86
+
87
+ class ThreadStopCommand < Command # :nodoc:
88
+ self.control = true
89
+ self.need_context = true
90
+
91
+ def regexp
92
+ /^\s*th(?:read)?\s+stop\s+(\d+)\s*$/
93
+ end
94
+
95
+ def execute
96
+ c = get_context(@match[1].to_i)
97
+ case
98
+ when c == @state.context
99
+ print_msg "It's the current thread."
100
+ when c.ignored?
101
+ print_msg "Can't stop the debugger thread."
102
+ else
103
+ c.suspend
104
+ print_context(c)
105
+ end
106
+ end
107
+
108
+ class << self
109
+ def help_command
110
+ 'thread'
111
+ end
112
+
113
+ def help(cmd)
114
+ %{
115
+ th[read] stop <nnn>\t\tstop thread nnn
116
+ }
117
+ end
118
+ end
119
+ end
120
+
121
+ class ThreadCurrentCommand < Command # :nodoc:
122
+ self.need_context = true
123
+
124
+ def regexp
125
+ /^\s*th(?:read)?\s+c(?:ur(?:rent)?)?\s*$/
126
+ end
127
+
128
+ def execute
129
+ print_context(@state.context)
130
+ end
131
+
132
+ class << self
133
+ def help_command
134
+ 'thread'
135
+ end
136
+
137
+ def help(cmd)
138
+ %{
139
+ th[read] c[ur[rent]]\t\tshow current thread
140
+ }
141
+ end
142
+ end
143
+ end
144
+
145
+ class ThreadResumeCommand < Command # :nodoc:
146
+ self.control = true
147
+ self.need_context = true
148
+
149
+ def regexp
150
+ /^\s*th(?:read)?\s+resume\s+(\d+)\s*$/
151
+ end
152
+
153
+ def execute
154
+ c = get_context(@match[1].to_i)
155
+ case
156
+ when c == @state.context
157
+ print_msg "It's the current thread."
158
+ when c.ignored?
159
+ print_msg "Can't resume the debugger thread."
160
+ else
161
+ c.resume
162
+ print_context(c)
163
+ end
164
+ end
165
+
166
+ class << self
167
+ def help_command
168
+ 'thread'
169
+ end
170
+
171
+ def help(cmd)
172
+ %{
173
+ th[read] resume <nnn>\t\tresume thread nnn
174
+ }
175
+ end
176
+ end
177
+ end
178
+ end