ruby-debug 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,125 @@
1
+ module Debugger
2
+ module FrameFunctions
3
+ def format_frame(frame, pos)
4
+ file, line, id = frame.file, frame.line, frame.id
5
+ "#%d %s:%s%s\n" % [pos + 1, file, line, (id ? ":in `#{id.id2name}'" : "")]
6
+ end
7
+ end
8
+
9
+ class WhereCommand < Command
10
+ include FrameFunctions
11
+
12
+ def regexp
13
+ /^\s*(?:w(?:here)?|f(?:rame)?)$/
14
+ end
15
+
16
+ def execute
17
+ @state.context.frames.each_with_index do |frame, idx|
18
+ if idx == @state.frame_pos
19
+ print "--> "
20
+ else
21
+ print " "
22
+ end
23
+ print format_frame(frame, idx)
24
+ end
25
+ end
26
+
27
+ class << self
28
+ def help_command
29
+ %w|where frame|
30
+ end
31
+
32
+ def help(cmd)
33
+ if cmd == 'where'
34
+ %{
35
+ w[here]\tdisplay frames
36
+ }
37
+ else
38
+ %{
39
+ f[rame]\t\talias for where
40
+ }
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ class UpCommand < Command
47
+ include FrameFunctions
48
+
49
+ def regexp
50
+ /^\s*(?:(up)(?:\s+(\d+))?|(f)(?:rame)?(?:\s+(\d+)))\s*$/
51
+ end
52
+
53
+ def execute
54
+ if @match[1]
55
+ cmd, arg = @match.captures
56
+ else
57
+ cmd, arg = @match.captures[2..-1]
58
+ end
59
+ @state.previous_line = nil
60
+ if cmd == 'f'
61
+ @state.frame_pos = arg.to_i - 1
62
+ else
63
+ @state.frame_pos += (arg ? arg.to_i : 1)
64
+ end
65
+ @state.frame_pos = 0 if @state.frame_pos < 0
66
+ if @state.frame_pos >= @state.context.frames.size
67
+ @state.frame_pos = @state.context.frames.size - 1
68
+ print "At toplevel\n"
69
+ end
70
+ frame = @state.context.frames[@state.frame_pos]
71
+ @state.binding, @state.file, @state.line = frame.binding, frame.file, frame.line
72
+ print format_frame(frame, @state.frame_pos)
73
+ end
74
+
75
+ class << self
76
+ def help_command
77
+ %w|up frame|
78
+ end
79
+
80
+ def help(cmd)
81
+ if cmd == 'up'
82
+ %{
83
+ up[ nn]\tmove to higher frame
84
+ }
85
+ else
86
+ %{
87
+ f[rame] n\tselect nth frame
88
+ }
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ class DownCommand < Command
95
+ include FrameFunctions
96
+
97
+ def regexp
98
+ /^\s*down(?:\s+(\d+))?$/
99
+ end
100
+
101
+ def execute
102
+ @state.previous_line = nil
103
+ @state.frame_pos -= @match[1] ? @match[1].to_i : 1
104
+ if @state.frame_pos < 0
105
+ @state.frame_pos = 0
106
+ print "At stack bottom\n"
107
+ end
108
+ frame = @state.context.frames[@state.frame_pos]
109
+ @state.binding, @state.file, @state.line = frame.binding, frame.file, frame.line
110
+ print format_frame(frame, @state.frame_pos)
111
+ end
112
+
113
+ class << self
114
+ def help_command
115
+ 'down'
116
+ end
117
+
118
+ def help(cmd)
119
+ %{
120
+ down[ nn]\tmove to lower frame
121
+ }
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,47 @@
1
+ module Debugger
2
+ class HelpCommand < Command
3
+ self.control = true
4
+
5
+ def regexp
6
+ /^\s*h(?:elp)?(?:\s+(.+))?$/
7
+ end
8
+
9
+ def execute
10
+ print "ruby-debug help v.#{Debugger::VERSION}\n"
11
+ cmds = @state.commands.select{ |cmd| [cmd.help_command].flatten.include?(@match[1]) }
12
+ unless cmds.empty?
13
+ help = cmds.map{ |cmd| cmd.help(@match[1]) }.join
14
+ print help.split("\n").reject{|l| l =~ /^\s*$/ }.map{|l| l.gsub(/^ +/, '')}.join("\n")
15
+ else
16
+ print "Available commands:\n"
17
+ cmds = @state.commands.map{ |cmd| cmd.help_command }
18
+ cmds = cmds.flatten.uniq.sort
19
+
20
+ buf = ""
21
+ cmds.each do |cmd|
22
+ if buf.length + cmd.length > 70
23
+ print "%s\n", buf
24
+ buf = ""
25
+ else
26
+ buf << cmd << ' '
27
+ end
28
+ end
29
+ print "%s\n", buf if buf.length > 0
30
+ end
31
+ print "\n"
32
+ end
33
+
34
+ class << self
35
+ def help_command
36
+ 'help'
37
+ end
38
+
39
+ def help(cmd)
40
+ %{
41
+ h[elp]\t\tprint this help
42
+ h[elp] command\tprint help on command
43
+ }
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,67 @@
1
+ module Debugger
2
+ class ListCommand < Command
3
+ def regexp
4
+ /^\s*l(?:ist)?(?:\s+(.+))?$/
5
+ end
6
+
7
+ def execute
8
+ if not @match[1]
9
+ b = @state.previous_line ? @state.previous_line + 10 : @state.line - 5
10
+ e = b + 9
11
+ elsif @match[1] == '-'
12
+ b = @state.previous_line ? @state.previous_line - 10 : @state.line - 5
13
+ e = b + 9
14
+ elsif @match[1] == '='
15
+ @state.previous_line = nil
16
+ b = @state.line - 5
17
+ e = b + 9
18
+ else
19
+ b, e = @match[1].split(/[-,]/)
20
+ if e
21
+ b = b.to_i
22
+ e = e.to_i
23
+ else
24
+ b = b.to_i - 5
25
+ e = b + 9
26
+ end
27
+ end
28
+ @state.previous_line = b
29
+ display_list(b, e, @state.file, @state.line)
30
+ end
31
+
32
+ class << self
33
+ def help_command
34
+ 'list'
35
+ end
36
+
37
+ def help(cmd)
38
+ %{
39
+ l[ist]\t\tlist forward
40
+ l[ist] -\tlist backward
41
+ l[ist] =\tlist current line
42
+ l[ist] nn-mm\tlist given lines
43
+ }
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def display_list(b, e, file, line)
50
+ print "[%d, %d] in %s\n", b, e, file
51
+ if lines = Debugger.source_for(file)
52
+ n = 0
53
+ b.upto(e) do |n|
54
+ if n > 0 && lines[n-1]
55
+ if n == line
56
+ print "=> %d %s\n", n, lines[n-1].chomp
57
+ else
58
+ print " %d %s\n", n, lines[n-1].chomp
59
+ end
60
+ end
61
+ end
62
+ else
63
+ print "No sourcefile available for %s\n", file
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,53 @@
1
+ module Debugger
2
+ class MethodCommand < Command
3
+ def regexp
4
+ /^\s*m(?:ethod)?\s+(?:(i(:?nstance)?)\s)?/
5
+ end
6
+
7
+ def execute
8
+ if @match[1]
9
+ obj = debug_eval(@match.post_match)
10
+
11
+ len = 0
12
+ for v in obj.methods.sort
13
+ len += v.size + 1
14
+ if len > 70
15
+ len = v.size + 1
16
+ print "\n"
17
+ end
18
+ print "%s ", v
19
+ end
20
+ print "\n"
21
+ else
22
+ obj = debug_eval(@match.post_match)
23
+ unless obj.kind_of? Module
24
+ print "Should be Class/Module: %s\n", @match.post_match
25
+ else
26
+ len = 0
27
+ for v in obj.instance_methods(false).sort
28
+ len += v.size + 1
29
+ if len > 70
30
+ len = v.size + 1
31
+ print "\n"
32
+ end
33
+ print "%s ", v
34
+ end
35
+ print "\n"
36
+ end
37
+ end
38
+ end
39
+
40
+ class << self
41
+ def help_command
42
+ 'method'
43
+ end
44
+
45
+ def help(cmd)
46
+ %{
47
+ m[ethod] i[nstance] <obj>\tshow methods of object
48
+ m[ethod] <class|module>\t\tshow instance methods of class or module
49
+ }
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,104 @@
1
+ module Debugger
2
+ class NextCommand < Command
3
+ def regexp
4
+ /^\s*n(?:ext)?(?:\s+(\d+))?$/
5
+ end
6
+
7
+ def execute
8
+ steps = @match[1] ? @match[1].to_i : 1
9
+ @state.context.step_over steps, @state.context.frames.size - @state.frame_pos
10
+ @state.proceed
11
+ end
12
+
13
+ class << self
14
+ def help_command
15
+ 'next'
16
+ end
17
+
18
+ def help(cmd)
19
+ %{
20
+ n[ext][ nnn]\tgo over one line or till line nnn
21
+ }
22
+ end
23
+ end
24
+ end
25
+
26
+ class StepCommand < Command
27
+ def regexp
28
+ /^\s*s(?:tep)?(?:\s+(\d+))?$/
29
+ end
30
+
31
+ def execute
32
+ @state.context.stop_next = @match[1] ? @match[1].to_i : 1
33
+ @state.proceed
34
+ end
35
+
36
+ class << self
37
+ def help_command
38
+ 'step'
39
+ end
40
+
41
+ def help(cmd)
42
+ %{
43
+ s[tep][ nnn]\tstep (into methods) one line or till line nnn
44
+ }
45
+ end
46
+ end
47
+ end
48
+
49
+ class FinishCommand < Command
50
+ def regexp
51
+ /^\s*fin(?:ish)?$/
52
+ end
53
+
54
+ def execute
55
+ if @state.frame_pos == @state.context.frames.size
56
+ print "\"finish\" not meaningful in the outermost frame.\n"
57
+ else
58
+ @state.context.stop_frame = @state.context.frames.size - @state.frame_pos
59
+ @state.frame_pos = 0
60
+ @state.proceed
61
+ end
62
+ end
63
+
64
+ class << self
65
+ def help_command
66
+ 'finish'
67
+ end
68
+
69
+ def help(cmd)
70
+ %{
71
+ fin[ish]\treturn to outer frame
72
+ }
73
+ end
74
+ end
75
+ end
76
+
77
+ class ContinueCommand < Command
78
+ def regexp
79
+ /^\s*c(?:ont)?$|^\s*r(?:un)?$/
80
+ end
81
+
82
+ def execute
83
+ @state.proceed
84
+ end
85
+
86
+ class << self
87
+ def help_command
88
+ %w|cont run|
89
+ end
90
+
91
+ def help(cmd)
92
+ if cmd == 'cont'
93
+ %{
94
+ c[ont]\trun until program ends or hit breakpoint
95
+ }
96
+ else
97
+ %{
98
+ r[un]\talias for cont
99
+ }
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,164 @@
1
+ module Debugger
2
+ module ThreadFunctions
3
+ def display_context(c)
4
+ if c.thread == Thread.current
5
+ print "+"
6
+ else
7
+ print " "
8
+ end
9
+ print "%d ", c.thnum
10
+ print "%s\t", c.thread.inspect
11
+ last_frame = c.frames.first
12
+ if last_frame
13
+ print "%s:%d", last_frame.file, last_frame.line
14
+ end
15
+ print "\n"
16
+ end
17
+ end
18
+
19
+ class ThreadListCommand < Command
20
+ include ThreadFunctions
21
+
22
+ def regexp
23
+ /^\s*th(?:read)?\s+l(?:ist)?\s*$/
24
+ end
25
+
26
+ def execute
27
+ threads = Debugger.contexts.sort_by{|c| c.thnum}.each do |c|
28
+ display_context(c)
29
+ end
30
+ end
31
+
32
+ class << self
33
+ def help_command
34
+ 'thread'
35
+ end
36
+
37
+ def help(cmd)
38
+ %{
39
+ th[read] l[ist]\t\t\tlist all threads
40
+ }
41
+ end
42
+ end
43
+ end
44
+
45
+ class ThreadSwitchCommand < Command
46
+ include ThreadFunctions
47
+
48
+ def regexp
49
+ /^\s*th(?:read)?\s+(?:sw(?:itch)?\s+)?(\d+)\s*$/
50
+ end
51
+
52
+ def execute
53
+ c = get_context(@match[1].to_i)
54
+ if c == @state.context
55
+ print "It's the current thread.\n"
56
+ else
57
+ display_context(c)
58
+ c.stop_next = 1
59
+ c.thread.run
60
+ @state.proceed
61
+ end
62
+ end
63
+
64
+ class << self
65
+ def help_command
66
+ 'thread'
67
+ end
68
+
69
+ def help(cmd)
70
+ %{
71
+ th[read] [sw[itch]] <nnn>\tswitch thread context to nnn
72
+ }
73
+ end
74
+ end
75
+ end
76
+
77
+ class ThreadStopCommand < Command
78
+ include ThreadFunctions
79
+
80
+ def regexp
81
+ /^\s*th(?:read)?\s+stop\s+(\d+)\s*$/
82
+ end
83
+
84
+ def execute
85
+ c = get_context(@match[1].to_i)
86
+ if c == @state.context
87
+ print "It's the current thread.\n"
88
+ elsif c.thread.stop?
89
+ print "Already stopped.\n"
90
+ else
91
+ display_context(c)
92
+ c.set_suspend
93
+ end
94
+ end
95
+
96
+ class << self
97
+ def help_command
98
+ 'thread'
99
+ end
100
+
101
+ def help(cmd)
102
+ %{
103
+ th[read] stop <nnn>\t\tstop thread nnn
104
+ }
105
+ end
106
+ end
107
+ end
108
+
109
+ class ThreadCurrentCommand < Command
110
+ include ThreadFunctions
111
+
112
+ def regexp
113
+ /^\s*th(?:read)?\s+c(?:ur(?:rent)?)?\s*$/
114
+ end
115
+
116
+ def execute
117
+ display_context(@state.context)
118
+ end
119
+
120
+ class << self
121
+ def help_command
122
+ 'thread'
123
+ end
124
+
125
+ def help(cmd)
126
+ %{
127
+ th[read] c[ur[rent]]\t\tshow current thread
128
+ }
129
+ end
130
+ end
131
+ end
132
+
133
+ class ThreadResumeCommand < Command
134
+ include ThreadFunctions
135
+
136
+ def regexp
137
+ /^\s*th(?:read)?\s+resume\s+(\d+)\s*$/
138
+ end
139
+
140
+ def execute
141
+ c = get_context(@match[1].to_i)
142
+ if c == @state.context
143
+ print "It's the current thread.\n"
144
+ elsif !c.thread.stop?
145
+ print "Already running."
146
+ else
147
+ display_context(c)
148
+ c.thread.run
149
+ end
150
+ end
151
+
152
+ class << self
153
+ def help_command
154
+ 'thread'
155
+ end
156
+
157
+ def help(cmd)
158
+ %{
159
+ th[read] resume <nnn>\t\tresume thread nnn
160
+ }
161
+ end
162
+ end
163
+ end
164
+ end