rbx-trepanning 0.0.7-universal-rubinius-1.2 → 0.0.8-universal-rubinius-1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/ChangeLog +236 -0
  2. data/NEWS +16 -0
  3. data/Rakefile +60 -11
  4. data/app/breakpoint.rb +5 -1
  5. data/app/brkptmgr.rb +5 -0
  6. data/app/cmd_parse.kpeg +225 -0
  7. data/app/cmd_parse.rb +209 -0
  8. data/app/cmd_parser.rb +1894 -0
  9. data/app/default.rb +0 -1
  10. data/app/method.rb +12 -8
  11. data/app/options.rb +2 -9
  12. data/app/validate.rb +2 -2
  13. data/bin/trepanx +3 -3
  14. data/lib/trepanning.rb +9 -6
  15. data/processor/breakpoint.rb +5 -19
  16. data/processor/command/alias.rb +4 -5
  17. data/processor/command/base/submgr.rb +2 -2
  18. data/processor/command/break.rb +44 -66
  19. data/processor/command/condition.rb +2 -0
  20. data/processor/command/continue.rb +11 -41
  21. data/processor/command/disassemble.rb +2 -0
  22. data/processor/command/eval.rb +20 -8
  23. data/processor/command/exit.rb +3 -2
  24. data/{doc → processor/command/help}/.gitignore +0 -0
  25. data/processor/command/help/command.txt +48 -0
  26. data/processor/command/help/filename.txt +40 -0
  27. data/processor/command/help/location.txt +37 -0
  28. data/processor/command/help.rb +52 -73
  29. data/processor/command/info_subcmd/breakpoints.rb +35 -13
  30. data/processor/command/info_subcmd/files.rb +34 -25
  31. data/processor/command/info_subcmd/frame.rb +67 -0
  32. data/processor/command/kill.rb +0 -1
  33. data/processor/command/restart.rb +8 -8
  34. data/processor/command/save.rb +58 -0
  35. data/processor/command/set_subcmd/trace_subcmd/buffer.rb +1 -1
  36. data/processor/command/set_subcmd/trace_subcmd/print.rb +1 -1
  37. data/processor/command/show.rb +7 -6
  38. data/processor/command/step.rb +16 -3
  39. data/processor/command/tbreak.rb +1 -1
  40. data/processor/disassemble.rb +1 -1
  41. data/processor/help.rb +20 -0
  42. data/processor/load_cmds.rb +53 -4
  43. data/processor/location.rb +47 -1
  44. data/processor/main.rb +4 -9
  45. data/processor/mock.rb +3 -3
  46. data/processor/running.rb +16 -17
  47. data/processor/validate.rb +171 -159
  48. data/rbx-trepanning.gemspec +1 -1
  49. data/test/example/debugger-stop.rb +16 -0
  50. data/test/functional/test-break-name.rb +1 -1
  51. data/test/functional/test-eval.rb +115 -0
  52. data/test/functional/test-tbreak.rb +1 -1
  53. data/test/integration/helper.rb +5 -2
  54. data/test/unit/cmd-helper.rb +1 -1
  55. data/test/unit/test-app-cmd_parse.rb +97 -0
  56. data/test/unit/test-app-cmd_parser.rb +22 -0
  57. data/test/unit/test-app-options.rb +1 -0
  58. data/test/unit/test-app-validate.rb +2 -2
  59. data/test/unit/test-cmd-break.rb +47 -5
  60. data/test/unit/test-completion.rb +2 -1
  61. data/test/unit/test-proc-location.rb +11 -0
  62. data/test/unit/test-proc-validate.rb +68 -30
  63. metadata +26 -11
  64. data/doc/debugger.html +0 -108
@@ -0,0 +1,40 @@
1
+ syntax for indicating a filename
2
+
3
+ There are two ways you can give a file name:
4
+ - unadorned (without double-quotes) with possible escapes
5
+ - as a double-quoted string with possible escapes in the string
6
+
7
+ Probably most of the time a file name will be specified in the first
8
+ form, without using quotes. If the file name however has a space or a
9
+ colon in it, escape that character with a backslash. Also, if you need
10
+ to enter a backslash and the character followinng that is unlucky
11
+ enough to be a colon, space, or backslash use two backslashes. Some
12
+ examples:
13
+
14
+ irb.rb => irb.rb
15
+ /tmp/irb.rb => /tmp/irb.rb
16
+ C\:irb.rb => C:irb.rb
17
+ C\:\irb.rb => C:\irb.rb
18
+ C\:\\irb.rb => C:\irb.rb # Note: double slash not needed
19
+ \\new.rb => \new.rb # Note: double slash, or filename has newline
20
+ my\ file.rb => my file.rb
21
+
22
+
23
+ The quoted string is useful if you have a file name that contains
24
+ several characters that normally confuse the debugger parser, notably
25
+ a space, newline, or a colon. The quoted string starts with a double
26
+ quote ("). Escape sequences are allowed inside the string to be able
27
+ to enter tabs or newlines, or a double quote inside the string. The
28
+ list of translations is as follows:
29
+
30
+ \t => <tab>
31
+ \n => <newline>
32
+ \" => "
33
+ \\ => \
34
+
35
+ Here are some examples of quoted filenames:
36
+
37
+ "This is a file with blanks.rb" => This is a file with blanks.rb
38
+ "/tmp/RubyProgram \"foo\".rb => /tmp/RubyProgram "foo".rb
39
+ "/Ruby\nProgram.rb" => /tmp/Ruby
40
+ Program.rb
@@ -0,0 +1,37 @@
1
+ syntax for source code locations; e.g. used "list" and "break"
2
+
3
+ Locations are used to indicates places in the source code or the
4
+ places in bytecode compiled from source code. Locations are used in
5
+ the listing commands like "list" or "disassemble"; they are also used
6
+ in "breakpoint" commands like "break", "tbreak" and "continue"
7
+
8
+ A location is either some sort of "container" and a position inside
9
+ that container. A container is either a file name or a method
10
+ name. And a position is either a line number or a bytecode offset.
11
+ Bytecode offsets are prefaced with an '@'. So 4 is a line number 4, but
12
+ @4 is bytecode offset 4.
13
+
14
+ File names are distinguished from method names purely by semantic
15
+ means. That its "foo" (without the quotes) could conceivably be
16
+ either a method or a file name. The debugger does a file check to see
17
+ if "foo" is a file.
18
+
19
+ In gdb, locations are often given using a filename a colon and a line
20
+ number. That is supported here are well. So myfile.rb:5 indicates line 5
21
+ of file "myfile.rb". But since we also allow method names you can also use
22
+ "gcd:5" to indicate line 5 of method "gcd".
23
+
24
+ Line numbers in methods are not relative to the beginning of the
25
+ method but relative the beginning of source text that contains the
26
+ method. This is also how Ruby stores line numbers for methods which
27
+ are shown for example in a backtrace. So all of this hopefully will
28
+ feel familiar and consistent.
29
+
30
+ Instead of using a colon to separate the container and the position,
31
+ you can also use spacs. So "gcd 5" is the same as gcd:5.
32
+
33
+ If the filename has an embedded blank in it, you can indicate that by
34
+ using a backslash escape. For example: "file\ with\ blanks.rb"
35
+
36
+
37
+
@@ -3,7 +3,6 @@ require 'rubygems'; require 'require_relative'
3
3
  require_relative 'base/cmd'
4
4
  require_relative '../../app/complete'
5
5
  class Trepan::Command::HelpCommand < Trepan::Command
6
-
7
6
  unless defined?(HELP)
8
7
  NAME = File.basename(__FILE__, '.rb')
9
8
  HELP = <<-HELP
@@ -34,26 +33,27 @@ See also 'examine' and 'whatis'.
34
33
  'running' => 'Running the program',
35
34
  'status' => 'Status inquiries',
36
35
  'support' => 'Support facilities',
37
- 'stack' => 'Examining the call stack'
36
+ 'stack' => 'Examining the call stack',
37
+ 'syntax' => 'Debugger command syntax'
38
38
  }
39
39
  CATEGORY = 'support'
40
40
  NEED_STACK = false
41
41
  SHORT_HELP = 'Print commands or give help for command(s)'
42
+
43
+ ROOT_DIR = File.dirname(RequireRelative.abs_file)
44
+ HELP_DIR = File.join(ROOT_DIR, 'help')
42
45
  end
43
46
 
44
- def complete(prefix)
45
- matches = Trepan::Complete.complete_token(CATEGORIES.keys +
46
- %w(* syntax all) +
47
- @proc.commands.keys, prefix)
48
- aliases = Trepan::Complete.complete_token_filtered(@proc.aliases, prefix,
49
- matches)
50
- (matches + aliases).sort
51
- end
47
+ class Syntax
48
+ def initialize(syntax_files); @syntax_files = syntax_files; end
49
+ def complete(prefix)
50
+ matches = Trepan::Complete.complete_token(syntax_files, prefix)
51
+ end
52
+ end
52
53
 
53
54
  def complete(prefix)
54
- matches = Trepan::Complete.complete_token(CATEGORIES.keys +
55
- %w(* syntax all) +
56
- @proc.commands.keys, prefix)
55
+ matches = Trepan::Complete.complete_token(CATEGORIES.keys + %w(* all) +
56
+ @proc.commands.keys, prefix)
57
57
  aliases = Trepan::Complete.complete_token_filtered(@proc.aliases, prefix,
58
58
  matches)
59
59
  (matches + aliases).sort
@@ -67,18 +67,17 @@ See also 'examine' and 'whatis'.
67
67
 
68
68
  # List the command categories and a short description of each.
69
69
  def list_categories
70
- section 'Classes of commands:'
70
+ section 'Help classes:'
71
71
  CATEGORIES.keys.sort.each do |cat|
72
72
  msg("%-13s -- %s" % [cat, CATEGORIES[cat]])
73
73
  end
74
74
  final_msg = '
75
- Type "help" followed by a class name for a list of commands in that class.
76
- Type "help syntax" for information on debugger command syntax.
77
- Type "help aliases" for a list of current aliases
78
- Type "help macros" for a list of current macros
75
+ Type "help" followed by a class name for a list of help items in that class.
76
+ Type "help aliases" for a list of current aliases.
77
+ Type "help macros" for a list of current macros.
79
78
  Type "help *" for the list of all commands, macros and aliases.
80
79
  Type "help all" for the list of all commands.
81
- Type "help REGEXP" for the list of commands matching /^#{REGEXP}/
80
+ Type "help REGEXP" for the list of commands matching /^#{REGEXP}/.
82
81
  Type "help CLASS *" for the list of all commands in class CLASS.
83
82
  Type "help" followed by command name for full documentation.
84
83
  '
@@ -99,7 +98,7 @@ Type "help" followed by command name for full documentation.
99
98
  elsif cmd_name =~ /^macros$/i
100
99
  show_macros
101
100
  elsif cmd_name =~ /^syntax$/i
102
- show_command_syntax
101
+ show_command_syntax(args)
103
102
  elsif cmd_name =~ /^all$/i
104
103
  CATEGORIES.sort.each do |category|
105
104
  show_category(category[0], [])
@@ -127,7 +126,7 @@ Type "help" followed by command name for full documentation.
127
126
  elsif @proc.macros.member?(cmd_name)
128
127
  msg "#{cmd_name} is a macro which expands to:"
129
128
  msg " #{@proc.macros[cmd_name]}", {:unlimited => true}
130
- else
129
+ else
131
130
  matches = @proc.commands.keys.grep(/^#{cmd_name}/).sort rescue []
132
131
  if matches.empty?
133
132
  errmsg("No commands found matching /^#{cmd_name}/. Try \"help\".")
@@ -148,7 +147,7 @@ Type "help" followed by command name for full documentation.
148
147
 
149
148
  # Show short help for all commands in `category'.
150
149
  def show_category(category, args)
151
-
150
+
152
151
  if args.size == 1 && args[0] == '*'
153
152
  section "Commands in class %s:" % category
154
153
 
@@ -158,7 +157,7 @@ Type "help" followed by command name for full documentation.
158
157
  width = settings[:maxwidth]
159
158
  return columnize_commands(cmds)
160
159
  end
161
-
160
+
162
161
  msg('')
163
162
  section "Command class: %s" % category
164
163
  msg('')
@@ -167,56 +166,35 @@ Type "help" followed by command name for full documentation.
167
166
  msg("%-13s -- %s" % [name, @proc.commands[name].short_help])
168
167
  end
169
168
  end
170
-
171
- def show_command_syntax
172
- section "Debugger command syntax"
173
- msg <<-EOS
174
- Command tokenization syntax is very simple-minded.
175
-
176
- If a line starts with #, the command is ignored.
177
- If a line starts with !, the line is eval'd.
178
-
179
- If the command you want eval'd uses the Ruby ! initally, add that
180
- after the first !.
181
-
182
- Commands are split at whereever ;; appears. This process disregards
183
- any quotes or other symbols that have meaning in Ruby. The strings
184
- after the leading command string are put back on a command queue.
185
-
186
- Within a single command, tokens are then white-space split. Again,
187
- this process disregards quotes or symbols that have meaning in Ruby.
188
- Some commands like 'eval' and 'macro' have access to the untokenized
189
- string entered and make use of that rather than the tokenized list.
190
-
191
- The leading token is first looked up in the macro table. If it
192
- found there, the expansion is replaces the current command and possibly
193
- other commands pushed onto a command queue. Next the leading token is
194
- looked up in the debugger alias table and the name may be substituted
195
- there. Finally, the leading token is looked up in the debugger alias
196
- table. If a match is found, the command name and arguments are
197
- dispatched to the command object that process the command.
198
-
199
- If the command is not found and "auto eval" is set on, then the
200
- command is eval'd in the context that the program is currently stopped
201
- at. If "auto eval" is not set on, then we display an error message
202
- that the entered string is "undefined".
203
-
204
- If you want irb-like command-processing, it's possible to go into an
205
- irb shell with the "irb" command. It is also possible to arrange going
206
- into an irb shell every time you enter the debugger.
207
-
208
- Examples:
209
-
210
- # This line does nothing. It is a comment
211
- s # by default, this is an alias for the "step" command
212
- !s # shows the value of variable step.
213
- !!s # Evaluates !s (or "not s"). The first ! is indicates evaluate.
214
- info program;; list # Runs two commands "info program" and "list"
215
- pr "hi ;;-)" # Syntax error since ;; splits the line and " is not closed.
216
- !puts "hi ;;-)" # One way to do the above.
217
-
218
- See also "alias", "irb", "set auto eval", and "set auto irb".
219
- EOS
169
+
170
+ def syntax_files
171
+ @syntax_files ||= Dir.glob(File.join(HELP_DIR, '*.txt')).map do |txt|
172
+ basename = File.basename(txt, '.txt')
173
+ end
174
+ end
175
+
176
+ def show_command_syntax(args)
177
+ if args.size == 2
178
+ @syntax_summary_help ||= {}
179
+ section "List of syntax help"
180
+ syntax_files.each do |name|
181
+ @syntax_summary_help[name] ||=
182
+ File.open(File.join(HELP_DIR, "#{name}.txt")).readline.chomp
183
+ msg " %-8s -- %s" % [name, @syntax_summary_help[name]]
184
+ end
185
+ else
186
+ args[2..-1].each do |name|
187
+ if syntax_files.member?(name)
188
+ @syntax_help ||= {}
189
+ @syntax_help[name] =
190
+ File.open(File.join(HELP_DIR, "#{name}.txt")).readlines[2..-1].join
191
+ section "Debugger syntax for a #{name}:"
192
+ msg @syntax_help[name]
193
+ else
194
+ errmsg "No syntax help for #{name}"
195
+ end
196
+ end
197
+ end
220
198
  end
221
199
 
222
200
  def show_macros
@@ -248,4 +226,5 @@ if __FILE__ == $0
248
226
  cmd.run %W(#{cmd.name} s<>)
249
227
  puts '=' * 40
250
228
  p cmd.complete('br')
229
+ p cmd.complete('un')
251
230
  end
@@ -4,6 +4,7 @@ require 'rubygems'; require 'require_relative'
4
4
  require_relative '../base/subcmd'
5
5
 
6
6
  class Trepan::Subcommand::InfoBreakpoints < Trepan::Subcommand
7
+ unless defined?(HELP)
7
8
  Trepanning::Subcommand.set_name_prefix(__FILE__, self)
8
9
  HELP = <<-EOH
9
10
  #{PREFIX.join(' ')} [num1 ...] [verbose]
@@ -20,10 +21,39 @@ The "enb" column indicates whether the breakpoint is enabled.
20
21
 
21
22
  The "Where" column indicates where the breakpoint is located.
22
23
  EOH
23
- MIN_ABBREV = 'br'.size
24
- SHORT_HELP = 'Status of user-settable breakpoints'
24
+ MIN_ABBREV = 'br'.size
25
+ SHORT_HELP = 'Status of user-settable breakpoints'
26
+ end
25
27
 
28
+ def bpprint(bp, verbose=false)
29
+ disp = bp.temp? ? 'del ' : 'keep '
30
+ disp += bp.enabled? ? 'y ' : 'n '
31
+ msg "%-4dbreakpoint %s at %s" % [bp.id, disp, bp.describe]
32
+ if bp.condition && bp.condition != 'true'
33
+ msg("\tstop %s %s" %
34
+ [bp.negate ? "unless" : "only if", bp.condition])
35
+ end
36
+ if bp.hits > 0
37
+ ss = (bp.hits > 1) ? 's' : ''
38
+ msg("\tbreakpoint already hit %d time%s" %
39
+ [bp.hits, ss])
40
+ end
41
+
42
+ if bp.ignore > 0
43
+ msg("\tignore next %d hits" % bp.ignore)
44
+ end
45
+ end
46
+
26
47
  def run(args)
48
+ verbose = false
49
+ unless args.empty?
50
+ if 'verbose' == args[-1]
51
+ verbose = true
52
+ args.pop
53
+ end
54
+ end
55
+
56
+
27
57
  show_all =
28
58
  if args.size > 2
29
59
  opts = {
@@ -37,23 +67,15 @@ EOH
37
67
  else
38
68
  true
39
69
  end
40
-
70
+
41
71
  bpmgr = @proc.brkpts
42
72
  if bpmgr.empty? && @proc.dbgr.deferred_breakpoints.empty?
43
73
  msg('No breakpoints.')
44
74
  else
45
75
  # There's at least one
46
- section "Num Breakpoint"
76
+ section("Num Type Disp Enb Where")
47
77
  bpmgr.list.each do |bp|
48
- msg "%3d: %s" % [bp.id, bp.describe]
49
- if bp.condition && bp.condition != 'true'
50
- msg("\tstop only if %s" % bp.condition)
51
- end
52
- if bp.hits > 0
53
- ss = (bp.hits > 1) ? 's' : ''
54
- msg("\tbreakpoint already hit %d time%s" %
55
- [bp.hits, ss])
56
- end
78
+ bpprint(bp)
57
79
  end
58
80
  section 'Deferred breakpoints...'
59
81
  @proc.dbgr.deferred_breakpoints.each_with_index do |bp, i|
@@ -9,7 +9,7 @@ require_relative '../../../app/complete'
9
9
  class Trepan::Subcommand::InfoFiles < Trepan::Subcommand
10
10
  unless defined?(HELP)
11
11
  Trepanning::Subcommand.set_name_prefix(__FILE__, self)
12
- DEFAULT_FILE_ARGS = %w(size mtime sha1)
12
+ DEFAULT_FILE_ARGS = %w(size mtime sha1 cm)
13
13
 
14
14
  HELP = <<-EOH
15
15
  #{CMD} [{FILENAME|.|*} [all|ctime|brkpts|mtime|sha1|size|stat]]
@@ -24,6 +24,7 @@ Sub options which can be shown about a file are:
24
24
 
25
25
  brkpts -- Line numbers where there are statement boundaries.
26
26
  These lines can be used in breakpoint commands.
27
+ cm -- Top-level compiled method found for this file
27
28
  ctime -- File creation time
28
29
  mtime -- File modification time
29
30
  sha1 -- A SHA1 hash of the source text. This may be useful in comparing
@@ -47,7 +48,7 @@ EOH
47
48
  NEED_STACK = false
48
49
  end
49
50
 
50
- # completion %w(all brkpts iseq sha1 size stat)
51
+ # completion %w(all brkpts cm sha1 size stat)
51
52
 
52
53
  include Trepanning
53
54
 
@@ -65,8 +66,15 @@ EOH
65
66
  return if args.size < 2
66
67
  args << '.' if 2 == args.size
67
68
  if '*' == args[2]
68
- section 'Files names cached:'
69
- msg columnize_commands(file_list.sort)
69
+ section 'Canonic Files names cached:'
70
+ primary = LineCache.class_variable_get('@@file_cache')
71
+ remap = LineCache.class_variable_get('@@file2file_remap')
72
+ msg columnize_commands(remap.keys.uniq.sort)
73
+ names = remap.keys - primary.keys
74
+ unless names.empty?
75
+ section 'Non-canonic names cached:'
76
+ msg columnize_commands(names.sort)
77
+ end
70
78
  return
71
79
  end
72
80
  filename =
@@ -76,19 +84,21 @@ EOH
76
84
  return false
77
85
  nil
78
86
  else
79
- File.expand_path(@proc.frame.file)
87
+ frame_file = @proc.frame_file
88
+ LineCache::map_file(frame_file) || File.expand_path(frame_file)
80
89
  end
81
90
  else
82
91
  args[2]
83
92
  end
84
93
  args += DEFAULT_FILE_ARGS if args.size == 3
85
94
 
86
- m = filename + ' is'
87
- canonic_name = LineCache::map_file(filename) || filename
95
+ m = filename
96
+ canonic_name = @proc.canonic_file(filename)
97
+ canonic_name = LineCache::map_file(canonic_name) || canonic_name
88
98
  if LineCache::cached?(canonic_name)
89
- m += " cached in debugger"
99
+ m += " is cached in debugger"
90
100
  if canonic_name != filename
91
- m += (' as:' + canonic_name)
101
+ m += (" as:\n " + canonic_name)
92
102
  end
93
103
  m += '.'
94
104
  msg(m)
@@ -110,9 +120,11 @@ EOH
110
120
  matches.sort.each { |match_file| msg "\t%s" % match_file }
111
121
  return
112
122
  elsif 1 == matches.size
113
- canonic_name = LineCache::map_file(matches[1])
123
+ canonic_name = LineCache::map_file(matches[0])
124
+ m += " matched debugger cache file:\n " + canonic_name
125
+ msg m
114
126
  else
115
- msg(m + ' not cached in debugger.')
127
+ msg(m + ' is not cached in debugger.')
116
128
  return
117
129
  end
118
130
  end
@@ -138,7 +150,7 @@ EOH
138
150
  if %w(all brkpts).member?(arg)
139
151
  unless seen[:brkpts]
140
152
  msg("Possible breakpoint line numbers:")
141
- lines = LineCache::trace_line_numbers(canonic_name)
153
+ lines = LineCache.trace_line_numbers(canonic_name)
142
154
  fmt_lines = columnize_numbers(lines)
143
155
  msg(fmt_lines)
144
156
  end
@@ -153,19 +165,16 @@ EOH
153
165
  processed_arg = seen[:ctime] = true
154
166
  end
155
167
 
156
- # if %w(all iseq).member?(arg)
157
- # unless seen[:iseq]
158
- # if SCRIPT_ISEQS__.member?(canonic_name)
159
- # msg("File contains instruction sequences:")
160
- # SCRIPT_ISEQS__[canonic_name].each do |iseq|
161
- # msg("\t %s %s" % [iseq, iseq.name.inspect])
162
- # end
163
- # else
164
- # msg("Instruction sequences not recorded; there may be some, though.")
165
- # end
166
- # end
167
- # processed_arg = seen[:iseq] = true
168
- # end
168
+ if %w(all cm).member?(arg)
169
+ unless seen[:cm]
170
+ if cm = LineCache.compiled_method(canonic_name)
171
+ msg("File has compiled method: #{cm}")
172
+ else
173
+ msg("Compiled method not recorded; there may be some, though.")
174
+ end
175
+ end
176
+ processed_arg = seen[:cm] = true
177
+ end
169
178
 
170
179
  if %w(all mtime).member?(arg)
171
180
  unless seen[:mtime]
@@ -0,0 +1,67 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'rubygems'; require 'require_relative'
3
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
4
+ require_relative '../base/subcmd'
5
+
6
+ class Trepan::Subcommand::InfoFrame < Trepan::Subcommand
7
+ unless defined?(HELP)
8
+ Trepanning::Subcommand.set_name_prefix(__FILE__, self)
9
+ HELP = <<-EOH
10
+ #{CMD}
11
+
12
+ Show information about the selected frame. The fields we list are:
13
+
14
+ * A source container and name (e.g. "file" or "string" and the value)
15
+ * The actual number of arguments passed in
16
+ * The 'arity' or permissible number of arguments passed it. -1 indicates
17
+ variable number
18
+ * The frame "type", e.g. TOP, METHOD, BLOCK, EVAL, CFUNC etc.
19
+ * The return value if the frame is at a return point
20
+ * The PC offset we are currently at; May be omitted of no instruction
21
+ sequence
22
+
23
+ A backtrace shows roughly the same information in a more compact form.
24
+
25
+ Example form inside File.basename('foo')
26
+
27
+ Frame basename
28
+ file : /tmp/c-func.rb # actually location of caller
29
+ line : 2 # inherited from caller
30
+ argc : 1 # One out argument supplied: 'foo'
31
+ arity : -1 # Variable number of args, can have up to 2 arguments.
32
+ type : CFUNC (A C function)
33
+
34
+
35
+ See also: backtrace
36
+ EOH
37
+ MIN_ABBREV = 'fr'.size # Note we have "info file"
38
+ NEED_STACK = true
39
+ SHORT_HELP = 'Show information about the selected frame'
40
+ end
41
+
42
+ def run(args)
43
+ frame = @proc.frame
44
+ loc = frame.vm_location
45
+ section "Frame %2d: #{frame.method.name}" % frame.number
46
+ msg " in : #{loc.describe_receiver}#{loc.name}"
47
+ msg " file : %s" % loc.method.active_path
48
+ msg " line : %s" % frame.line
49
+ # msg " argc : %d" % frame.argc
50
+ msg " arity : %d" % frame.method.arity
51
+ # msg " type : %s" % frame.type
52
+ msg " offset: %d" % frame.ip
53
+ # if %w(return c-return).member?(@proc.event)
54
+ # ret_val = Trepan::Frame.value_returned(@proc.frame, @proc.event)
55
+ # msg " Return: %s" % ret_val
56
+ # end
57
+ end
58
+
59
+ end
60
+
61
+ if __FILE__ == $0
62
+ # Demo it.
63
+ require_relative '../../mock'
64
+ dbgr, cmd = MockDebugger::setup('info')
65
+ cmd = MockDebugger::sub_setup(Trepan::Subcommand::InfoFrame, false)
66
+ cmd.run(cmd.prefix)
67
+ end
@@ -50,7 +50,6 @@ Examples:
50
50
  errmsg("Signal name '#{sig}' is not a signal I know about.\n")
51
51
  return false
52
52
  end
53
- # FIXME: reinstate
54
53
  if 'KILL' == sig || Signal['KILL'] == sig
55
54
  @proc.intf.finalize
56
55
  end
@@ -26,19 +26,19 @@ new copy of the debugger is used.
26
26
  dbgr = @proc.dbgr
27
27
  argv = dbgr.restart_argv
28
28
  if argv and argv.size > 0
29
- # unless File.executable?(argv[0])
30
- # msg(["File #{argv[0]} not executable.",
31
- # "Adding Ruby interpreter."])
32
- # argv.unshift Trepanning::ruby_path
33
- # end
34
29
  @proc.run_cmd(%w(show args))
35
30
  if not confirm('Restart (exec)?', false)
36
31
  msg "Restart not confirmed"
37
32
  else
38
- msg 'Restarting...'
39
- @proc.run_cmd(%w(save))
40
- # FIXME: Run atexit finalize routines?
33
+ if defined?(Trepan::PROG_UNRESOLVED_SCRIPT) &&
34
+ position = argv.index(Trepan::PROG_UNRESOLVED_SCRIPT)
35
+ save_filename = @proc.save_commands(:erase =>true)
36
+ argv.insert(position, '--command', save_filename) if save_filename
37
+ end
41
38
  Dir.chdir(Rubinius::OS_STARTUP_DIR)
39
+ msg 'Restarting using...'
40
+ msg "\t #{argv.inspect}"
41
+ @proc.finalize
42
42
  exec(*argv)
43
43
  end
44
44
  else
@@ -0,0 +1,58 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative 'base/cmd'
5
+ class Trepan::Command::SaveCommand < Trepan::Command
6
+
7
+ unless defined?(HELP)
8
+ NAME = File.basename(__FILE__, '.rb')
9
+ HELP = <<-HELP
10
+ #{NAME} [--[no-]erase] [--output|-o FILENAME]
11
+
12
+ Save settings to file FILENAME. If FILENAME not given one will be made
13
+ selected.
14
+ HELP
15
+
16
+ CATEGORY = 'running'
17
+ MAX_ARGS = 1 # Need at most this many
18
+ SHORT_HELP = 'Send debugger state to a file'
19
+
20
+ DEFAULT_OPTIONS = { :erase => true, }
21
+ end
22
+
23
+ def parse_options(options, args) # :nodoc
24
+ parser = OptionParser.new do |opts|
25
+ opts.on("-e", "--[no-]erase",
26
+ "Add line to erase after reading") do
27
+ |v|
28
+ options[:erase] = v
29
+ end
30
+ opts.on("-o", "--output FILE", String,
31
+ "Save file to FILE. ") do
32
+ |filename|
33
+ options[:filename] = filename
34
+ end
35
+ end
36
+ parser.parse(args)
37
+ return options
38
+ end
39
+
40
+ # This method runs the command
41
+ def run(args)
42
+ options = parse_options(DEFAULT_OPTIONS.dup, args[1..-1])
43
+ save_filename = @proc.save_commands(options)
44
+ msg "Debugger commands written to file: #{save_filename}" if
45
+ save_filename
46
+ end
47
+ end
48
+
49
+ if __FILE__ == $0
50
+ require_relative '../mock'
51
+ dbgr, cmd = MockDebugger::setup
52
+ require 'tmpdir'
53
+ cmd.run([cmd.name])
54
+ # require_relative '../../lib/trepanning'; debugger
55
+ cmd.run([cmd.name, '--erase',
56
+ '--output', File.join(Dir.tmpdir, 'save_file.txt')])
57
+ # A good test would be to see we can read in those files without error.
58
+ end
@@ -4,7 +4,7 @@ require 'rubygems'; require 'require_relative'
4
4
  require_relative '../../base/subsubcmd'
5
5
  require_relative '../trace'
6
6
  class Trepan::SubSubcommand::SetTraceBuffer < Trepan::SetBoolSubSubcommand
7
- Trepanning::Subcommand.set_name_prefix(__FILE__, self)
7
+ Trepanning::SubSubcommand.set_name_prefix(__FILE__, self)
8
8
  unless defined?(HELP)
9
9
  HELP = <<-EOH
10
10
  #{CMD} [on|off|1|0]
@@ -4,7 +4,7 @@ require 'rubygems'; require 'require_relative'
4
4
  require_relative '../../base/subsubcmd'
5
5
  require_relative '../trace'
6
6
  class Trepan::SubSubcommand::SetTracePrint < Trepan::SetBoolSubSubcommand
7
- Trepanning::Subcommand.set_name_prefix(__FILE__, self)
7
+ Trepanning::SubSubcommand.set_name_prefix(__FILE__, self)
8
8
  unless defined?(HELP)
9
9
  HELP = <<-EOH
10
10
  "#{CMD} [on|off|1|0]