ruby-debug 0.10.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. data/CHANGES +94 -2
  2. data/ChangeLog +5225 -0
  3. data/README +30 -1
  4. data/Rakefile +55 -24
  5. data/bin/rdebug +249 -128
  6. data/cli/ruby-debug/command.rb +30 -3
  7. data/cli/ruby-debug/commands/breakpoints.rb +54 -24
  8. data/cli/ruby-debug/commands/catchpoint.rb +13 -12
  9. data/cli/ruby-debug/commands/condition.rb +49 -0
  10. data/cli/ruby-debug/commands/continue.rb +32 -0
  11. data/cli/ruby-debug/commands/control.rb +19 -43
  12. data/cli/ruby-debug/commands/disassemble.RB +38 -0
  13. data/cli/ruby-debug/commands/display.rb +1 -1
  14. data/cli/ruby-debug/commands/edit.rb +48 -0
  15. data/cli/ruby-debug/commands/enable.rb +78 -35
  16. data/cli/ruby-debug/commands/eval.rb +6 -5
  17. data/cli/ruby-debug/commands/finish.rb +42 -0
  18. data/cli/ruby-debug/commands/frame.rb +64 -33
  19. data/cli/ruby-debug/commands/help.rb +19 -15
  20. data/cli/ruby-debug/commands/info.rb +295 -36
  21. data/cli/ruby-debug/commands/irb.rb +3 -1
  22. data/cli/ruby-debug/commands/list.rb +27 -50
  23. data/cli/ruby-debug/commands/quit.rb +38 -0
  24. data/cli/ruby-debug/commands/reload.rb +40 -0
  25. data/cli/ruby-debug/commands/save.rb +80 -0
  26. data/cli/ruby-debug/commands/{settings.rb → set.rb} +50 -12
  27. data/cli/ruby-debug/commands/show.rb +83 -27
  28. data/cli/ruby-debug/commands/source.rb +36 -0
  29. data/cli/ruby-debug/commands/stepping.rb +36 -72
  30. data/cli/ruby-debug/commands/threads.rb +32 -23
  31. data/cli/ruby-debug/commands/variables.rb +34 -4
  32. data/cli/ruby-debug/helper.rb +10 -75
  33. data/cli/ruby-debug/interface.rb +72 -9
  34. data/cli/ruby-debug/processor.rb +203 -100
  35. data/doc/rdebug.1 +7 -2
  36. data/rdbg.rb +33 -0
  37. data/test/{test-ruby-debug-base.rb → base/base.rb} +27 -29
  38. data/test/base/binding.rb +31 -0
  39. data/test/base/catchpoint.rb +26 -0
  40. data/test/base/load.rb +40 -0
  41. data/test/data/annotate.cmd +29 -0
  42. data/test/data/annotate.right +137 -0
  43. data/test/data/break_bad.cmd +18 -0
  44. data/test/data/break_bad.right +28 -0
  45. data/test/data/breakpoints.cmd +38 -0
  46. data/test/data/breakpoints.right +98 -0
  47. data/test/data/condition.cmd +28 -0
  48. data/test/data/condition.right +65 -0
  49. data/test/data/ctrl.cmd +23 -0
  50. data/test/data/ctrl.right +69 -0
  51. data/test/{display.cmd → data/display.cmd} +7 -1
  52. data/test/{display.right → data/display.right} +13 -6
  53. data/test/data/dollar-0.right +2 -0
  54. data/test/data/dollar-0a.right +2 -0
  55. data/test/data/dollar-0b.right +2 -0
  56. data/test/data/edit.cmd +12 -0
  57. data/test/data/edit.right +19 -0
  58. data/test/{breakpoints.cmd → data/emacs_basic.cmd} +0 -0
  59. data/test/{breakpoints.right → data/emacs_basic.right} +24 -12
  60. data/test/data/enable.cmd +20 -0
  61. data/test/data/enable.right +36 -0
  62. data/test/data/finish.cmd +16 -0
  63. data/test/data/finish.right +43 -0
  64. data/test/{frame.cmd → data/frame.cmd} +2 -0
  65. data/test/{frame.right → data/frame.right} +8 -2
  66. data/test/{help.cmd → data/help.cmd} +8 -0
  67. data/test/data/help.right +21 -0
  68. data/test/data/history.right +7 -0
  69. data/test/data/info-thread.cmd +13 -0
  70. data/test/data/info-thread.right +37 -0
  71. data/test/data/info-var-bug2.cmd +5 -0
  72. data/test/data/info-var-bug2.right +10 -0
  73. data/test/{info-var.cmd → data/info-var.cmd} +3 -3
  74. data/test/{info-var.right → data/info-var.right} +20 -15
  75. data/test/{info.cmd → data/info.cmd} +10 -1
  76. data/test/data/info.right +65 -0
  77. data/test/data/linetrace.cmd +6 -0
  78. data/test/data/linetrace.right +32 -0
  79. data/test/data/linetracep.cmd +7 -0
  80. data/test/data/linetracep.right +25 -0
  81. data/test/data/list.cmd +19 -0
  82. data/test/data/list.right +127 -0
  83. data/test/data/noquit.right +1 -0
  84. data/test/data/output.cmd +6 -0
  85. data/test/data/output.right +41 -0
  86. data/test/data/post-mortem-next.cmd +8 -0
  87. data/test/data/post-mortem-next.right +14 -0
  88. data/test/data/post-mortem-osx.right +31 -0
  89. data/test/data/post-mortem.cmd +13 -0
  90. data/test/data/post-mortem.right +31 -0
  91. data/test/{quit.cmd → data/quit.cmd} +2 -5
  92. data/test/data/quit.right +9 -0
  93. data/test/data/raise.cmd +11 -0
  94. data/test/data/raise.right +26 -0
  95. data/test/{setshow.cmd → data/setshow.cmd} +0 -1
  96. data/test/{setshow.right → data/setshow.right} +0 -1
  97. data/test/data/source.cmd +5 -0
  98. data/test/data/source.right +15 -0
  99. data/test/{stepping.cmd → data/stepping.cmd} +6 -2
  100. data/test/{stepping.right → data/stepping.right} +13 -3
  101. data/test/data/test-init-cygwin.right +7 -0
  102. data/test/data/test-init-osx.right +4 -0
  103. data/test/data/test-init.right +5 -0
  104. data/test/data/trace.right +23 -0
  105. data/test/dollar-0.rb +5 -0
  106. data/test/except-bug2.rb +7 -0
  107. data/test/gcd-dbg-nox.rb +31 -0
  108. data/test/gcd-dbg.rb +30 -0
  109. data/test/helper.rb +44 -14
  110. data/test/info-var-bug.rb +2 -0
  111. data/test/info-var-bug2.rb +2 -0
  112. data/test/null.rb +1 -0
  113. data/test/output.rb +2 -0
  114. data/test/pm-base.rb +22 -0
  115. data/test/pm.rb +11 -0
  116. data/test/raise.rb +3 -0
  117. data/test/tdebug.rb +88 -40
  118. data/test/test-annotate.rb +25 -0
  119. data/test/test-break-bad.rb +25 -0
  120. data/test/test-breakpoints.rb +14 -17
  121. data/test/test-condition.rb +25 -0
  122. data/test/test-ctrl.rb +54 -0
  123. data/test/test-display.rb +15 -15
  124. data/test/test-dollar-0.rb +39 -0
  125. data/test/test-edit.rb +26 -0
  126. data/test/test-emacs-basic.rb +26 -0
  127. data/test/test-enable.rb +25 -0
  128. data/test/test-finish.rb +34 -0
  129. data/test/test-frame.rb +15 -16
  130. data/test/test-help.rb +34 -18
  131. data/test/test-hist.rb +68 -0
  132. data/test/test-info-thread.rb +32 -0
  133. data/test/test-info-var.rb +28 -14
  134. data/test/test-info.rb +15 -17
  135. data/test/test-init.rb +41 -0
  136. data/test/test-list.rb +25 -0
  137. data/test/test-output.rb +26 -0
  138. data/test/test-pm.rb +46 -0
  139. data/test/test-quit.rb +19 -17
  140. data/test/test-raise.rb +25 -0
  141. data/test/test-setshow.rb +14 -13
  142. data/test/test-source.rb +25 -0
  143. data/test/test-stepping.rb +14 -14
  144. data/test/test-trace.rb +63 -0
  145. data/test/thread1.rb +26 -0
  146. metadata +125 -31
  147. data/cli/ruby-debug/commands/script.rb +0 -64
  148. data/runner.sh +0 -7
  149. data/test/help.right +0 -4
  150. data/test/info.right +0 -35
  151. data/test/quit.right +0 -22
  152. data/test/test-columnize.rb +0 -46
@@ -95,7 +95,7 @@ module Debugger
95
95
  if @state.display[pos-1]
96
96
  @state.display[pos-1][0] = nil
97
97
  else
98
- print "Display expression %d is not defined\n", pos
98
+ errmsg "Display expression %d is not defined.\n", pos
99
99
  end
100
100
  end
101
101
  end
@@ -0,0 +1,48 @@
1
+ module Debugger
2
+ class Edit < Command # :nodoc:
3
+ self.allow_in_control = true
4
+ def regexp
5
+ /^\s* ed(?:it)? (?:\s+(.*))?$/ix
6
+ end
7
+
8
+ def execute
9
+ if not @match[1] or @match[1].strip.empty?
10
+ unless @state.context
11
+ errmsg "We are not in a state that has an associated file.\n"
12
+ return
13
+ end
14
+ file = @state.file
15
+ line_number = @state.line
16
+ elsif @pos_match = /([^:]+)[:]([0-9]+)/.match(@match[1])
17
+ file, line_number = @pos_match.captures
18
+ else
19
+ errmsg "Invalid file/line number specification: #{@match[1]}\n"
20
+ return
21
+ end
22
+ editor = ENV['EDITOR'] || 'ex'
23
+ if File.readable?(file)
24
+ system("#{editor} +#{line_number} #{file}")
25
+ else
26
+ errmsg "File \"#{file}\" is not readable.\n"
27
+ end
28
+ end
29
+
30
+ class << self
31
+ def help_command
32
+ 'edit'
33
+ end
34
+
35
+ def help(cmd)
36
+ %{
37
+ Edit specified file.
38
+
39
+ With no argument, edits file containing most recent line listed.
40
+ Editing targets can also be specified in this:
41
+ FILE:LINENUM, to edit at that line in that file,
42
+ }
43
+ end
44
+ end
45
+ end
46
+
47
+
48
+ end # module Debugger
@@ -3,9 +3,11 @@ module Debugger
3
3
  module EnableDisableFunctions # :nodoc:
4
4
  def enable_disable_breakpoints(is_enable, args)
5
5
  breakpoints = Debugger.breakpoints.sort_by{|b| b.id }
6
- largest = breakpoints.inject(0){|largest, b| largest = b.id if b.id > largest}
6
+ largest = breakpoints.inject(0) do |largest, b|
7
+ largest = b.id if b.id > largest
8
+ end
7
9
  if 0 == largest
8
- print "No breakpoints have been set.\n"
10
+ errmsg "No breakpoints have been set.\n"
9
11
  return
10
12
  end
11
13
  args.each do |pos|
@@ -13,14 +15,25 @@ module Debugger
13
15
  return nil unless pos
14
16
  breakpoints.each do |b|
15
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
16
25
  b.enabled = ("Enable" == is_enable)
17
- return
26
+ break
18
27
  end
19
28
  end
20
29
  end
21
30
  end
22
31
 
23
32
  def enable_disable_display(is_enable, args)
33
+ if 0 == @state.display.size
34
+ errmsg "No display expressions have been set.\n"
35
+ return
36
+ end
24
37
  args.each do |pos|
25
38
  pos = get_int(pos, "#{is_enable} display", 1, @state.display.size)
26
39
  return nil unless pos
@@ -31,14 +44,18 @@ module Debugger
31
44
  end
32
45
 
33
46
  class EnableCommand < Command # :nodoc:
34
- SubcmdStruct=Struct.new(:name, :min, :short_help) unless
35
- defined?(SubcmdStruct)
36
47
  Subcommands =
37
48
  [
38
- ['breakpoints', 2, "Enable specified breakpoints"],
39
- ['display', 2, "Enable some expressions to be displayed when program stops"],
40
- ].map do |name, min, short_help|
41
- SubcmdStruct.new(name, min, short_help)
49
+ ['breakpoints', 2, "Enable specified breakpoints",
50
+ "Give breakpoint numbers (separated by spaces) as arguments.
51
+ This is used to cancel the effect of the \"disable\" command."
52
+ ],
53
+ ['display', 2,
54
+ "Enable some expressions to be displayed when program stops",
55
+ "Arguments are the code numbers of the expressions to resume displaying.
56
+ Do \"info display\" to see current list of code numbers."],
57
+ ].map do |name, min, short_help, long_help|
58
+ SubcmdStruct.new(name, min, short_help, long_help)
42
59
  end unless defined?(Subcommands)
43
60
 
44
61
  def regexp
@@ -47,19 +64,17 @@ module Debugger
47
64
 
48
65
  def execute
49
66
  if not @match[1]
50
- print "\"enable\" must be followed \"display\", \"breakpoints\"" +
67
+ errmsg "\"enable\" must be followed \"display\", \"breakpoints\"" +
51
68
  " or breakpoint numbers.\n"
52
69
  else
53
70
  args = @match[1].split(/[ \t]+/)
54
- subcmd = args.shift.downcase
55
- for try_subcmd in Subcommands do
56
- if (subcmd.size >= try_subcmd.min) and
57
- (try_subcmd.name[0..subcmd.size-1] == subcmd)
58
- send("enable_#{try_subcmd.name}", args)
59
- return
60
- end
71
+ param = args.shift
72
+ subcmd = find(Subcommands, param)
73
+ if subcmd
74
+ send("enable_#{subcmd.name}", args)
75
+ else
76
+ send("enable_breakpoints", args.unshift(param))
61
77
  end
62
- send("enable_breakpoints", args.unshift(subcmd))
63
78
  end
64
79
  end
65
80
 
@@ -76,7 +91,21 @@ module Debugger
76
91
  'enable'
77
92
  end
78
93
 
79
- def help(cmd)
94
+ def help(args)
95
+ if args[1]
96
+ s = args[1]
97
+ subcmd = Subcommands.find do |try_subcmd|
98
+ (s.size >= try_subcmd.min) and
99
+ (try_subcmd.name[0..s.size-1] == s)
100
+ end
101
+ if subcmd
102
+ str = subcmd.short_help + '.'
103
+ str += "\n" + subcmd.long_help if subcmd.long_help
104
+ return str
105
+ else
106
+ return "Invalid 'enable' subcommand '#{args[1]}'."
107
+ end
108
+ end
80
109
  s = %{
81
110
  Enable some things.
82
111
  This is used to cancel the effect of the "disable" command.
@@ -93,14 +122,16 @@ module Debugger
93
122
  end
94
123
 
95
124
  class DisableCommand < Command # :nodoc:
96
- SubcmdStruct=Struct.new(:name, :min, :short_help) unless
97
- defined?(SubcmdStruct)
98
125
  Subcommands =
99
126
  [
100
- ['breakpoints', 2, "Disable specified breakpoints"],
101
- ['display', 2, "Disable some display expressions when program stops"],
102
- ].map do |name, min, short_help|
103
- SubcmdStruct.new(name, min, short_help)
127
+ ['breakpoints', 1, "Disable some breakpoints",
128
+ "Arguments are breakpoint numbers with spaces in between.
129
+ A disabled breakpoint is not forgotten, but has no effect until reenabled."],
130
+ ['display', 1, "Disable some display expressions when program stops",
131
+ "Arguments are the code numbers of the expressions to stop displaying.
132
+ Do \"info display\" to see current list of code numbers."],
133
+ ].map do |name, min, short_help, long_help|
134
+ SubcmdStruct.new(name, min, short_help, long_help)
104
135
  end unless defined?(Subcommands)
105
136
 
106
137
  def regexp
@@ -109,19 +140,17 @@ module Debugger
109
140
 
110
141
  def execute
111
142
  if not @match[1]
112
- print "\"disable\" must be followed \"display\", \"breakpoints\"" +
143
+ errmsg "\"disable\" must be followed \"display\", \"breakpoints\"" +
113
144
  " or breakpoint numbers.\n"
114
145
  else
115
146
  args = @match[1].split(/[ \t]+/)
116
- subcmd = args.shift.downcase
117
- for try_subcmd in Subcommands do
118
- if (subcmd.size >= try_subcmd.min) and
119
- (try_subcmd.name[0..subcmd.size-1] == subcmd)
120
- send("disable_#{try_subcmd.name}", args)
121
- return
122
- end
147
+ param = args.shift
148
+ subcmd = find(Subcommands, param)
149
+ if subcmd
150
+ send("disable_#{subcmd.name}", args)
151
+ else
152
+ send("disable_breakpoints", args.unshift(param))
123
153
  end
124
- send("disable_breakpoints", args.unshift(subcmd))
125
154
  end
126
155
  end
127
156
 
@@ -138,7 +167,21 @@ module Debugger
138
167
  'disable'
139
168
  end
140
169
 
141
- def help(cmd)
170
+ def help(args)
171
+ if args[1]
172
+ s = args[1]
173
+ subcmd = Subcommands.find do |try_subcmd|
174
+ (s.size >= try_subcmd.min) and
175
+ (try_subcmd.name[0..s.size-1] == s)
176
+ end
177
+ if subcmd
178
+ str = subcmd.short_help + '.'
179
+ str += "\n" + subcmd.long_help if subcmd.long_help
180
+ return str
181
+ else
182
+ return "Invalid 'disable' subcommand '#{args[1]}'."
183
+ end
184
+ end
142
185
  s = %{
143
186
  Disable some things.
144
187
 
@@ -8,7 +8,8 @@ module Debugger
8
8
  def dbg_print(*args)
9
9
  $__dbg_interface.print(*args)
10
10
  end
11
- remove_method :puts if self.respond_to?(:puts)
11
+ remove_method :puts if self.respond_to?(:puts) &&
12
+ defined?(remove_method)
12
13
  def dbg_puts(*args)
13
14
  $__dbg_interface.print(*args)
14
15
  $__dbg_interface.print("\n")
@@ -22,7 +23,7 @@ module Debugger
22
23
  end
23
24
 
24
25
  class EvalCommand < Command # :nodoc:
25
- self.control = true
26
+ self.allow_in_control = true
26
27
 
27
28
  register_setting_get(:autoeval) do
28
29
  EvalCommand.unknown
@@ -69,7 +70,7 @@ module Debugger
69
70
  end
70
71
 
71
72
  class PPCommand < Command # :nodoc:
72
- self.control = true
73
+ self.allow_in_control = true
73
74
 
74
75
  def regexp
75
76
  /^\s*pp\s+/
@@ -99,7 +100,7 @@ module Debugger
99
100
  end
100
101
 
101
102
  class PutLCommand < Command # :nodoc:
102
- self.control = true
103
+ self.allow_in_control = true
103
104
 
104
105
  def regexp
105
106
  /^\s*putl\s+/
@@ -135,7 +136,7 @@ module Debugger
135
136
  end
136
137
 
137
138
  class PSCommand < Command # :nodoc:
138
- self.control = true
139
+ self.allow_in_control = true
139
140
 
140
141
  include EvalFunctions
141
142
 
@@ -0,0 +1,42 @@
1
+ module Debugger
2
+ # Implements the debugger 'finish' command.
3
+ class FinishCommand < Command
4
+ self.allow_in_post_mortem = false
5
+ self.need_context = true
6
+
7
+ def regexp
8
+ /^\s*fin(?:ish)? (?:\s+(.*))?$/x
9
+ end
10
+
11
+ def execute
12
+ max_frame = @state.context.stack_size - @state.frame_pos
13
+ if !@match[1] or @match[1].empty?
14
+ frame_pos = @state.frame_pos
15
+ else
16
+ frame_pos = get_int(@match[1], "Finish", 0, max_frame-1, 0)
17
+ return nil unless frame_pos
18
+ end
19
+ @state.context.stop_frame = frame_pos
20
+ @state.frame_pos = 0
21
+ @state.proceed
22
+ end
23
+
24
+ class << self
25
+ def help_command
26
+ 'finish'
27
+ end
28
+
29
+ def help(cmd)
30
+ %{
31
+ fin[ish] [frame-number]\tExecute until selected stack frame returns.
32
+
33
+ If no frame number is given, we run until the currently selected frame
34
+ returns. The currently selected frame starts out the most-recent
35
+ frame or 0 if no frame positioning (e.g "up", "down" or "frame") has
36
+ been performed. If a frame number is given we run until that frame
37
+ returns.
38
+ }
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,10 +1,11 @@
1
1
  module Debugger
2
2
  # Mix-in module to assist in command parsing.
3
3
  module FrameFunctions # :nodoc:
4
- def adjust_frame(frame_pos, absolute)
4
+ def adjust_frame(frame_pos, absolute, context=@state.context)
5
+ @state.frame_pos = 0 if context != @state.context
5
6
  if absolute
6
7
  if frame_pos < 0
7
- abs_frame_pos = @state.context.stack_size + frame_pos
8
+ abs_frame_pos = context.stack_size + frame_pos
8
9
  else
9
10
  abs_frame_pos = frame_pos
10
11
  end
@@ -12,11 +13,11 @@ module Debugger
12
13
  abs_frame_pos = @state.frame_pos + frame_pos
13
14
  end
14
15
 
15
- if abs_frame_pos >= @state.context.stack_size then
16
- print "Adjusting would put us beyond the oldest (initial) frame."
16
+ if abs_frame_pos >= context.stack_size then
17
+ errmsg "Adjusting would put us beyond the oldest (initial) frame.\n"
17
18
  return
18
19
  elsif abs_frame_pos < 0 then
19
- print "Adjusting would put us beyond the newest (innermost) frame."
20
+ errmsg "Adjusting would put us beyond the newest (innermost) frame.\n"
20
21
  return
21
22
  end
22
23
  if @state.frame_pos != abs_frame_pos then
@@ -24,22 +25,22 @@ module Debugger
24
25
  @state.frame_pos = abs_frame_pos
25
26
  end
26
27
 
27
- @state.file = @state.context.frame_file(@state.frame_pos)
28
- @state.line = @state.context.frame_line(@state.frame_pos)
28
+ @state.file = context.frame_file(@state.frame_pos)
29
+ @state.line = context.frame_line(@state.frame_pos)
29
30
 
30
31
  print_frame(@state.frame_pos, true)
31
32
  end
32
33
 
33
- def get_frame_call(prefix, pos)
34
- id = @state.context.frame_method(pos)
35
- klass = @state.context.frame_class(pos)
34
+ def get_frame_call(prefix, pos, context)
35
+ id = context.frame_method(pos)
36
+ klass = context.frame_class(pos)
36
37
  call_str = ""
37
38
  if id
38
- args = @state.context.frame_args(pos)
39
- locals = @state.context.frame_locals(pos)
39
+ args = context.frame_args(pos)
40
+ locals = context.frame_locals(pos)
40
41
  if Command.settings[:callstyle] != :short && klass
41
42
  if Command.settings[:callstyle] == :tracked
42
- arg_info = @state.context.frame_args_info(pos)
43
+ arg_info = context.frame_args_info(pos)
43
44
  end
44
45
  call_str << "#{klass}."
45
46
  end
@@ -75,10 +76,10 @@ module Debugger
75
76
  return call_str
76
77
  end
77
78
 
78
- def print_frame(pos, adjust = false)
79
- file = @state.context.frame_file(pos)
80
- line = @state.context.frame_line(pos)
81
- klass = @state.context.frame_class(pos)
79
+ def print_frame(pos, adjust = false, context=@state.context)
80
+ file = context.frame_file(pos)
81
+ line = context.frame_line(pos)
82
+ klass = context.frame_class(pos)
82
83
 
83
84
  unless Command.settings[:full_path]
84
85
  path_components = file.split(/[\\\/]/)
@@ -89,7 +90,7 @@ module Debugger
89
90
  end
90
91
 
91
92
  frame_num = "#%d " % pos
92
- call_str = get_frame_call(frame_num, pos)
93
+ call_str = get_frame_call(frame_num, pos, context)
93
94
  file_line = "at line %s:%d\n" % [CommandProcessor.canonic_file(file), line]
94
95
  print frame_num
95
96
  unless call_str.empty?
@@ -100,12 +101,16 @@ module Debugger
100
101
  end
101
102
  end
102
103
  print file_line
103
- print "\032\032%s:%d\n" % [CommandProcessor.canonic_file(file),
104
- line] if ENV['EMACS'] && adjust
104
+ if ENV['EMACS'] && adjust
105
+ fmt = (Debugger.annotate.to_i > 1 ?
106
+ "\032\032source %s:%d\n" : "\032\032%s:%d\n")
107
+ print fmt % [CommandProcessor.canonic_file(file), line]
108
+ end
105
109
  end
106
110
  end
107
111
 
108
- class WhereCommand < Command # :nodoc:
112
+ # Implements debugger "where" or "backtrace" command.
113
+ class WhereCommand < Command
109
114
  def regexp
110
115
  /^\s*(?:w(?:here)?|bt|backtrace)$/
111
116
  end
@@ -127,16 +132,21 @@ module Debugger
127
132
  end
128
133
 
129
134
  def help(cmd)
130
- if cmd == 'where'
135
+ s = if cmd == 'where'
131
136
  %{
132
- w[here]\tdisplay frames
133
- }
134
- else
137
+ w[here]\tdisplay stack frames
138
+ }
139
+ else
135
140
  %{
136
- bt|backtrace\t\talias for where
137
- }
138
- end
139
- end
141
+ bt|backtrace\t\talias for where - display stack frames
142
+ }
143
+ end
144
+ s += %{
145
+ Print the entire stack frame. Each frame is numbered, the most recent
146
+ frame is 0. frame number can be referred to in the "frame" command;
147
+ "up" and "down" add or subtract respectively to frame numbers shown.
148
+ The position of the current frame is marked with -->. }
149
+ end
140
150
  end
141
151
  end
142
152
 
@@ -190,18 +200,31 @@ module Debugger
190
200
 
191
201
  class FrameCommand < Command # :nodoc:
192
202
  def regexp
193
- /^\s* f(?:rame)? (?:\s+ (.*))? \s*$/x
203
+ / ^\s*
204
+ f(?:rame)?
205
+ (?: \s+ (\S+))? \s*
206
+ (?: thread \s+ (.*))? \s*
207
+ $/x
194
208
  end
195
209
 
196
210
  def execute
197
211
  if not @match[1]
198
- print "Missing a frame number argument.\n"
212
+ errmsg "Missing a frame number argument.\n"
199
213
  return
200
214
  else
201
215
  pos = get_int(@match[1], "Frame")
202
216
  return unless pos
203
217
  end
204
- adjust_frame(pos, true)
218
+ if @match[2]
219
+ context = parse_thread_num('frame', @match[2])
220
+ unless context
221
+ errmsg "Thread #{@match[2]} doesn't exist.\n"
222
+ return
223
+ end
224
+ else
225
+ context = @state.context
226
+ end
227
+ adjust_frame(pos, true, context)
205
228
  end
206
229
 
207
230
  class << self
@@ -211,12 +234,20 @@ module Debugger
211
234
 
212
235
  def help(cmd)
213
236
  %{
214
- f[rame] frame-number
237
+ f[rame] frame-number [thread thread-number]
215
238
  Move the current frame to the specified frame number.
216
239
 
217
240
  A negative number indicates position from the other end. So
218
241
  'frame -1' moves to the oldest frame, and 'frame 0' moves to
219
242
  the newest frame.
243
+
244
+ Without an argument, the command prints the current stack
245
+ frame. Since the current position is redisplayed, it may trigger a
246
+ resyncronization if there is a front end also watching over
247
+ things.
248
+
249
+ If a thread number is given then we set the context for evaluating
250
+ expressions to that frame of that thread.
220
251
  }
221
252
  end
222
253
  end