rbx-trepanning 0.0.3-universal-rubinius-1.2 → 0.0.4-universal-rubinius-1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. data/ChangeLog +152 -55
  2. data/NEWS +7 -0
  3. data/Rakefile +1 -1
  4. data/app/breakpoint.rb +3 -2
  5. data/app/breakpoint.rbc +207 -220
  6. data/app/brkptmgr.rb +84 -82
  7. data/app/brkptmgr.rbc +263 -193
  8. data/app/client.rb +61 -0
  9. data/app/client.rbc +1225 -0
  10. data/app/default.rb +17 -7
  11. data/app/default.rbc +302 -181
  12. data/app/display.rb +134 -21
  13. data/app/display.rbc +2176 -566
  14. data/app/iseq.rb +33 -11
  15. data/app/iseq.rbc +634 -243
  16. data/app/llvm.rbc +2576 -0
  17. data/app/options.rb +51 -20
  18. data/app/options.rb.orig +154 -0
  19. data/app/options.rbc +1148 -561
  20. data/app/rbx-llvm.rb +165 -0
  21. data/app/util.rb +1 -1
  22. data/app/util.rbc +38 -32
  23. data/bin/trepan.orig +0 -0
  24. data/bin/trepan.rej +11 -0
  25. data/bin/trepanx +13 -8
  26. data/bin/trepanx.compiled.rbc +373 -319
  27. data/interface/base_intf.rb +11 -5
  28. data/interface/base_intf.rbc +173 -70
  29. data/interface/client.rb +80 -0
  30. data/interface/client.rbc +1072 -0
  31. data/interface/comcodes.rb +18 -0
  32. data/interface/comcodes.rbc +343 -0
  33. data/interface/server.rb +143 -0
  34. data/interface/server.rbc +2213 -0
  35. data/interface/user.rb +1 -8
  36. data/interface/user.rbc +68 -165
  37. data/io/base_io.rb +56 -2
  38. data/io/base_io.rbc +727 -20
  39. data/io/tcpclient.rb +123 -0
  40. data/io/tcpclient.rbc +2327 -0
  41. data/io/tcpfns.rb +31 -0
  42. data/io/tcpfns.rbc +652 -0
  43. data/io/tcpserver.rb +138 -0
  44. data/io/tcpserver.rbc +2585 -0
  45. data/lib/trepanning.rb +91 -56
  46. data/lib/trepanning.rb.orig +433 -0
  47. data/lib/trepanning.rb.rej +11 -0
  48. data/lib/trepanning.rbc +1954 -1340
  49. data/processor/command/backtrace.rb +45 -15
  50. data/processor/command/base/cmd.rb +10 -6
  51. data/processor/command/base/subcmd.rb +16 -1
  52. data/processor/command/complete.rb +47 -0
  53. data/processor/command/continue.rb +4 -3
  54. data/processor/command/directory.rb +9 -1
  55. data/processor/command/disassemble.rb +22 -7
  56. data/processor/command/display.rb +82 -0
  57. data/processor/command/eval.rb +3 -1
  58. data/processor/command/exit.rb +4 -0
  59. data/processor/command/help.rb +69 -18
  60. data/processor/command/info_subcmd/breakpoints.rb +6 -8
  61. data/processor/command/info_subcmd/file.rb +5 -7
  62. data/processor/command/info_subcmd/method.rb +9 -9
  63. data/processor/command/info_subcmd/program.rb +3 -4
  64. data/processor/command/info_subcmd/variables.rb +4 -3
  65. data/processor/command/list.rb +8 -4
  66. data/processor/command/nexti.rb +2 -2
  67. data/processor/command/pr.rb +2 -2
  68. data/processor/command/ps.rb +2 -2
  69. data/processor/command/server.rb +72 -0
  70. data/processor/command/set_subcmd/auto.rb +2 -3
  71. data/processor/command/set_subcmd/basename.rb +3 -4
  72. data/processor/command/set_subcmd/debug.rb +2 -3
  73. data/processor/command/set_subcmd/different.rb +3 -4
  74. data/processor/command/set_subcmd/hidelevel.rb +6 -7
  75. data/processor/command/set_subcmd/highlight.rb +33 -0
  76. data/processor/command/set_subcmd/kernelstep.rb +3 -4
  77. data/processor/command/set_subcmd/max.rb +2 -4
  78. data/processor/command/set_subcmd/max_subcmd/string.rb +44 -22
  79. data/processor/command/set_subcmd/substitute.rb +2 -3
  80. data/processor/command/set_subcmd/trace.rb +3 -4
  81. data/processor/command/show_subcmd/alias.rb +3 -4
  82. data/processor/command/show_subcmd/args.rb +2 -3
  83. data/processor/command/show_subcmd/auto.rb +1 -2
  84. data/processor/command/show_subcmd/basename.rb +2 -3
  85. data/processor/command/show_subcmd/debug.rb +1 -2
  86. data/processor/command/show_subcmd/different.rb +2 -3
  87. data/processor/command/show_subcmd/hidelevel.rb +1 -2
  88. data/processor/command/show_subcmd/highlight.rb +24 -0
  89. data/processor/command/show_subcmd/kernelstep.rb +3 -6
  90. data/processor/command/show_subcmd/max.rb +4 -5
  91. data/processor/command/show_subcmd/trace.rb +9 -11
  92. data/processor/command/show_subcmd/version.rb +23 -0
  93. data/processor/command/source.rb +75 -31
  94. data/processor/command/undisplay.rb +59 -0
  95. data/processor/default.rb +4 -4
  96. data/processor/disassemble.rb +18 -5
  97. data/processor/display.rb +18 -0
  98. data/processor/location.rb +15 -5
  99. data/processor/main.rb +27 -13
  100. data/processor/mock.rb +12 -9
  101. data/processor/msg.rb +24 -9
  102. data/processor/stepping.rb +10 -12
  103. data/sample/list-terminal-colors.rb +139 -0
  104. data/sample/list-terminal-colors.rbc +2164 -0
  105. data/sample/rocky-dot-trepanrc.orig +0 -0
  106. data/sample/rocky-dot-trepanrc.rej +11 -0
  107. data/sample/rocky-dot-trepanxrc +14 -0
  108. data/sample/rocky-trepanx-colors.rb +39 -0
  109. data/test/data/fname-with-blank.right +3 -0
  110. data/test/data/inline-call.cmd +6 -0
  111. data/test/data/inline-call.right +13 -0
  112. data/test/data/quit.right +2 -0
  113. data/test/example/{gcd1.rb → gcd-server.rb} +4 -6
  114. data/test/example/gcd.rb +0 -0
  115. data/test/example/inline-call.rb +23 -0
  116. data/test/integration/helper.rb +8 -8
  117. data/test/integration/test-fname-with-blank.rb +5 -1
  118. data/test/integration/test-inline-call.rb +20 -0
  119. data/test/integration/test-quit.rb +5 -1
  120. data/test/unit/cmd-helper.rb +7 -4
  121. data/test/unit/mock-helper.rb +1 -0
  122. data/test/unit/test-app-brkpt.rb +4 -5
  123. data/test/unit/test-app-brkptmgr.rb +2 -2
  124. data/test/unit/test-app-iseq.rb +29 -14
  125. data/test/unit/test-app-options.rb +26 -5
  126. data/test/unit/test-base-subcmd.rb +1 -1
  127. data/test/unit/test-cmd-source.rb +34 -0
  128. data/test/unit/test-io-tcp.rb +33 -0
  129. data/test/unit/test-io-tcpclient.rb +53 -0
  130. data/test/unit/test-io-tcpfns.rb +17 -0
  131. data/test/unit/test-io-tcpserver.rb +50 -0
  132. data/test/unit/test-proc-main.rb +6 -2
  133. metadata +53 -10
  134. data/test/example/gcd-xx.rb +0 -18
@@ -4,32 +4,63 @@ require_relative './base/cmd'
4
4
  class Trepan::Command::BacktraceCommand < Trepan::Command
5
5
  ALIASES = %w(bt where)
6
6
  CATEGORY = 'stack'
7
+ MAX_ARGS = 2 # Need at most this many
7
8
  NAME = File.basename(__FILE__, '.rb')
8
9
  HELP = <<-HELP
9
- Show the call stack as a simple list.
10
+ #{NAME} [full] [COUNT]
10
11
 
11
- Passing "-v" will also show the values of all locals variables
12
- in each frame.
12
+ Print a backtrace of all stack frames, or innermost COUNT frames. Use
13
+ of the 'full' qualifier also prints the values of the local variables.
14
+
15
+ Passing "full" will also show the values of all locals variables in
16
+ each frame.
17
+
18
+ Normally outer frames which constitute debugger overhead are hidden
19
+ from view. However if a count is given and it runs into those hidden
20
+ frames, they will be shown.
21
+
22
+ Examples:
23
+
24
+ #{NAME}
25
+ #{NAME} full # show
26
+ #{NAME} 2
27
+ #{NAME} 3 full
28
+ #{NAME} full 3 # same as above
29
+ #{NAME} 1000 # probably will show any outer hidden frames
30
+
31
+ See also 'set hidelevel'.
13
32
  HELP
14
33
  NEED_STACK = true
15
34
  SHORT_HELP = 'Show the current call stack'
16
35
 
17
36
  def run(args)
18
- arg_str = args[1..-1].join(' ')
19
- verbose = (arg_str =~ /-v/)
20
-
21
- count =
22
- if m = /(\d+)/.match(arg_str)
23
- m[1].to_i
24
- else
25
- proc.stack_size
37
+ verbose_ary, count_ary = args[1..-1].partition {|item| item =~ /full/i}
38
+ verbose = !verbose_ary.empty?
39
+
40
+ if count_ary.size > 1
41
+ errmsg "Expecting only at most one parameter other than 'full'"
42
+ return
26
43
  end
27
44
 
28
- msg "Backtrace:"
45
+ if 1 == count_ary.size
46
+ begin
47
+ count = Integer(count_ary[0])
48
+ rescue
49
+ errmsg "Expecting count to be an integer; got #{count_ary[0]}"
50
+ return
51
+ end
52
+ elsif 0 == count_ary.size
53
+ count = proc.stack_size
54
+ else
55
+ errmsg "Wrong number of parameters. Expecting at most 2."
56
+ return
57
+ end
29
58
 
30
59
  @proc.dbgr.each_frame(@proc.top_frame) do |frame|
31
- return if count and frame.number >= count
32
-
60
+ if count and frame.number >= count
61
+ msg "(More stack frames follow...)" if count != proc.stack_size
62
+ return
63
+ end
33
64
 
34
65
  prefix = (frame == @proc.frame) ? '-->' : ' '
35
66
  msg "%s #%d %s" % [prefix, frame.number,
@@ -43,4 +74,3 @@ in each frame.
43
74
  end
44
75
  end
45
76
  end
46
-
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
- # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
3
  # Base class of all commands. Code common to all commands is here.
4
4
  # Note: don't end classname with Command (capital C) since main
5
5
  # will think this a command name like QuitCommand
@@ -47,21 +47,21 @@ class Trepan
47
47
  @proc.confirm(message, default)
48
48
  end
49
49
 
50
- def errmsg(message)
51
- @proc.errmsg(message)
50
+ def errmsg(message, opts={})
51
+ @proc.errmsg(message, opts)
52
52
  end
53
53
 
54
54
  def obj_const(obj, name)
55
55
  obj.class.const_get(name)
56
56
  end
57
57
 
58
- def msg(message)
59
- @proc.msg(message)
58
+ def msg(message, opts={})
59
+ @proc.msg(message, opts)
60
60
  end
61
61
 
62
62
  # Convenience short-hand for @dbgr.intf[-1].msg_nocr
63
63
  def msg_nocr(msg)
64
- @proc.msg_nocr(msg)
64
+ @proc.msg_nocr(msg, opts={})
65
65
  end
66
66
 
67
67
  def my_const(name)
@@ -87,6 +87,10 @@ class Trepan
87
87
  raise RuntimeError, 'You need to define this method elsewhere'
88
88
  end
89
89
 
90
+ def section(message, opts={})
91
+ @proc.section(message, opts)
92
+ end
93
+
90
94
  def settings
91
95
  @proc.settings
92
96
  end
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
- # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
3
  # A base class for debugger subcommands.
4
4
  #
5
5
  # Note: don't end classname with Command (capital C) since main
@@ -194,6 +194,18 @@ class Trepan
194
194
 
195
195
  end
196
196
 
197
+ module Trepanning
198
+ module Subcommand
199
+ module_function
200
+ def set_name_prefix(__file__, klass)
201
+ dirname = File.basename(File.dirname(File.expand_path(__file__)))
202
+ name = File.basename(__file__, '.rb')
203
+ klass.const_set('NAME', name)
204
+ klass.const_set('PREFIX', %W(#{dirname[0...-'_subcmd'.size]} #{name}))
205
+ end
206
+ end
207
+ end
208
+
197
209
  if __FILE__ == $0
198
210
  # Demo it.
199
211
  require_relative '../../mock'
@@ -210,4 +222,7 @@ if __FILE__ == $0
210
222
  # p subcmd.settings
211
223
  # p subcmd.show_onoff(subcmd.settings[:autoeval])
212
224
  # subcmd.run_set_int('', 'Just a test')
225
+ class Trepan::Subcommand::Foo < Trepan::Subcommand
226
+ Trepanning::Subcommand.set_name_prefix(__FILE__, self)
227
+ end
213
228
  end
@@ -0,0 +1,47 @@
1
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require 'rubygems'; require 'require_relative'
3
+ require_relative 'base/cmd'
4
+ class Trepan::Command::CompleteCommand < Trepan::Command
5
+
6
+ unless defined?(HELP)
7
+ HELP =
8
+ "complete COMMAND-PREFIX
9
+
10
+ List the completions for the rest of the line as a command.
11
+
12
+ NOTE: For now we just handle completion of the first token.
13
+ "
14
+ CATEGORY = 'support'
15
+ NAME = File.basename(__FILE__, '.rb')
16
+ NEED_STACK = false
17
+ SHORT_HELP = 'List the completions for the rest of the line as a command'
18
+ end
19
+
20
+ # This method runs the command
21
+ def run(args) # :nodoc
22
+ if args.size == 2
23
+ cmd_matches = @proc.commands.keys.select do |cmd|
24
+ cmd.start_with?(args[1])
25
+ end
26
+ alias_matches = @proc.aliases.keys.select do |cmd|
27
+ cmd.start_with?(args[1]) && !cmd_matches.member?(@proc.aliases[cmd])
28
+ end
29
+ (cmd_matches+alias_matches).sort.each do |match|
30
+ msg match
31
+ end
32
+ else # FIXME: handle more complex completions
33
+ end
34
+ end
35
+ end
36
+
37
+ if __FILE__ == $0
38
+ # Demo it.
39
+ require_relative '../mock'
40
+ dbgr, cmd = MockDebugger::setup
41
+ %w(d b bt).each do |prefix|
42
+ cmd.run [cmd.name, prefix]
43
+ puts '=' * 40
44
+ end
45
+ cmd.run %w(#{cmd.name} fdafsasfda)
46
+ puts '=' * 40
47
+ end
@@ -5,20 +5,21 @@ require_relative '../stepping'
5
5
  class Trepan::Command::ContinueCommand < Trepan::Command
6
6
  NAME = File.basename(__FILE__, '.rb')
7
7
  HELP = <<-HELP
8
- #{NAME} [breakpoint position]
8
+ #{NAME} [breakpoint-position]
9
9
 
10
10
  Leave the debugger loop and continue execution. Subsequent entry to
11
11
  the debugger however may occur via breakpoints or explicit calls, or
12
12
  exceptions.
13
13
 
14
- If a parameter is given, a temporary breakpoint is set at that position
14
+ If a parameter is given, a one-time breakpoint is set at that position
15
15
  before continuing.
16
16
 
17
17
  Examples:
18
18
  #{NAME}
19
19
  #{NAME} 10 # continue to line 10
20
+ #{NAME} Array#map # beginning of next Array#map call
20
21
 
21
- See also 'step', 'next', and 'nexti' commands.
22
+ See also 'step', 'next', 'finish', and 'nexti' commands.
22
23
  HELP
23
24
  ALIASES = %w(c cont)
24
25
  CATEGORY = 'running'
@@ -9,6 +9,8 @@ class Trepan::Command::DirectoryCommand < Trepan::Command
9
9
  MAX_ARGS = 1 # Need at most this many
10
10
  NAME = File.basename(__FILE__, '.rb')
11
11
  HELP = <<-HELP
12
+ #{NAME} [DIR]
13
+
12
14
  Add directory DIR to beginning of search path for source files.
13
15
  DIR can also be $cwd for the current working directory, or $cdir for the
14
16
  directory in which the debugged file start.
@@ -16,7 +18,12 @@ With no argument, reset the search path to $cdir:$cwd, the default.
16
18
 
17
19
  This command may be useful for debugging into Rubinius methods such as
18
20
  kernel/common/module.rb if have the source code somewhere.
21
+
22
+ Examples:
23
+ #{NAME} ~/.rvm/src/rbx-head # Adds an rvm-like directory to path
24
+ #{NAME} # reset to $cdir:$cwd
19
25
  HELP
26
+
20
27
  SHORT_HELP =
21
28
  'Add directory DIR to beginning of search path for source files'
22
29
  end
@@ -24,7 +31,8 @@ kernel/common/module.rb if have the source code somewhere.
24
31
  # This method runs the command
25
32
  def run(args) # :nodoc
26
33
  if args.size > 1
27
- settings[:directory] = "#{args[1]}:#{settings[:directory]}"
34
+ path = File.expand_path(args[1])
35
+ settings[:directory] = "#{path}:#{settings[:directory]}"
28
36
  msg "Source directories searched: #{settings[:directory]}"
29
37
  else
30
38
  if confirm('Reintialize source path to empty?', false)
@@ -1,3 +1,5 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
1
3
  require 'rubygems'; require 'require_relative'
2
4
  require_relative './base/cmd'
3
5
  require_relative '../../app/iseq'
@@ -32,6 +34,8 @@ Examples:
32
34
  lines = cm.lines
33
35
  next_line_ip = 0
34
36
  next_i = 1
37
+ prefixes = []
38
+ disasm = ''
35
39
  cm.decode.each do |insn|
36
40
  show_line =
37
41
  if insn.ip >= next_line_ip
@@ -43,8 +47,8 @@ Examples:
43
47
  false
44
48
  end
45
49
 
46
- prefix = Trepanning::ISeq::disasm_prefix(insn.ip, frame_ip, cm)
47
- str = "#{prefix} #{insn}"
50
+ prefixes << Trepan::ISeq::disasm_prefix(insn.ip, frame_ip, cm)
51
+ str = insn.to_s
48
52
  if show_line
49
53
  str +=
50
54
  if insn.instance_variable_get('@comment')
@@ -56,7 +60,20 @@ Examples:
56
60
  end
57
61
  str += "# line: #{line_no}"
58
62
  end
59
- msg str
63
+ disasm += "#{str}\n"
64
+ end
65
+
66
+ # FIXME DRY with ../disassemble.rb
67
+ if settings[:highlight]
68
+ require_relative '../../app/rbx-llvm'
69
+ @llvm_highlighter = CodeRay::Duo[:llvm, :term]
70
+ # llvm_scanner = CodeRay.scanner :llvm
71
+ # p llvm_scanner.tokenize(disasm)
72
+ disasm = @llvm_highlighter.encode(disasm)
73
+ end
74
+
75
+ disasm.split("\n").each_with_index do |inst, i|
76
+ msg ("#{prefixes[i]} #{inst}", :unlimited => true)
60
77
  end
61
78
  end
62
79
 
@@ -65,14 +82,12 @@ Examples:
65
82
  if 1 == args.size
66
83
  @proc.show_bytecode
67
84
  elsif 'all' == args[1]
68
- # FIXME: first msg is a section command.
69
- msg "Bytecode for #{@proc.frame.vm_location.describe}"
85
+ section "Bytecode for #{@proc.frame.vm_location.describe}"
70
86
  disassemble_method(current_method)
71
87
  else
72
88
  cm = @proc.parse_method(args[1])
73
89
  if cm
74
- # FIXME: first msg is a section command.
75
- msg "Bytecode for method #{args[1]}"
90
+ section "Bytecode for method #{args[1]}"
76
91
  disassemble_method(cm.executable)
77
92
  else
78
93
  errmsg "Method #{args[1]} not found"
@@ -0,0 +1,82 @@
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
+
6
+ class Trepan::Command::DisplayCommand < Trepan::Command
7
+
8
+ unless defined?(HELP)
9
+ NAME = File.basename(__FILE__, '.rb')
10
+ HELP = <<-HELP
11
+ #{name} [format] EXP
12
+
13
+ Print value of expression EXP each time the program stops. FMT may be
14
+ used before EXP and may be one of 'c' for char, 'x' for hex, 'o' for
15
+ octal, 'f' for float or 's' for string.
16
+
17
+ For now, display expressions are only evaluated when in the same
18
+ instruction sequence as the frame that was in effect when the display
19
+ expression was set. This is a departure from gdb and we may allow for
20
+ more flexibility in the future to specify whether this should be the
21
+ case or not.
22
+
23
+ With no argument, evaluate and display all currently requested
24
+ auto-display expressions. Use "undisplay" to cancel display
25
+ requests previously made.
26
+ HELP
27
+
28
+ CATEGORY = 'data'
29
+ NEED_STACK = false
30
+ SHORT_HELP = 'Display expressions when entering debugger'
31
+ end
32
+
33
+ def run(args)
34
+
35
+ if args.size == 1
36
+ # Display anything active
37
+ @proc.run_eval_display
38
+ else
39
+ if %w(/c /x /o /f /s).member?(args[1])
40
+ if 2 == args.size
41
+ errmsg("Expecting an expression after the format")
42
+ return
43
+ end
44
+ format = args[1]
45
+ expr = args[2..-1].join(' ')
46
+ else
47
+ format = nil
48
+ expr = args[1..-1].join(' ')
49
+ end
50
+
51
+ dp = @proc.displays.add(@proc.frame, expr, format)
52
+ unless dp
53
+ errmsg('Error evaluating "%s" in the current frame' % expr)
54
+ return
55
+ end
56
+ msg(dp.to_s(@proc.frame))
57
+ @proc.cmdloop_prehooks.insert_if_new(5, *@proc.display_hook)
58
+ end
59
+ end
60
+ end
61
+
62
+ if __FILE__ == $0
63
+ # Demo it.
64
+ require_relative '../mock'
65
+ dbgr, cmd = MockDebugger::setup
66
+
67
+ def run_cmd(cmd, args)
68
+ cmd.run(args)
69
+ puts '==' * 10
70
+ end
71
+
72
+ # run_cmd(cmd, [cmd.name])
73
+ # run_cmd(cmd, [cmd.name, '/x', '10'])
74
+ # run_cmd(cmd, [cmd.name, 'd'])
75
+ # run_cmd(cmd, [cmd.name])
76
+ e = 5
77
+ vm_locations = Rubinius::VM.backtrace(0, true)
78
+ cmd.proc.instance_variable_set('@frame ',
79
+ Trepan::Frame.new(self, 0, vm_locations[0]))
80
+
81
+ run_cmd(cmd, [cmd.name, 'e'])
82
+ end
@@ -1,3 +1,5 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
1
3
  require 'rubygems'; require 'require_relative'
2
4
  require_relative './base/cmd'
3
5
 
@@ -16,7 +18,7 @@ next to the inspect output of the value.
16
18
  NEED_STACK = true
17
19
  SHORT_HELP = 'Run code in the current context'
18
20
  def run(args)
19
- @proc.debug_eval(@proc.cmd_argstr, @proc.settings[:maxstring])
21
+ @proc.debug_eval(@proc.cmd_argstr, settings[:maxstring])
20
22
  end
21
23
  end
22
24
 
@@ -44,6 +44,10 @@ See also "kill".'
44
44
  return
45
45
  end
46
46
  exitrc = (args.size > 1) ? exitrc = Integer(args[1]) rescue 0 : 0
47
+
48
+ # FIXME: funnel to sort of more general finalize routine
49
+ @proc.dbgr.intf[-1].close
50
+
47
51
  # No graceful way to stop threads...
48
52
  # A little harsh, but for now let's go with this.
49
53
  exit! exitrc
@@ -1,11 +1,12 @@
1
- # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
1
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
2
  require 'rubygems'; require 'require_relative'
3
3
  require_relative 'base/cmd'
4
4
  class Trepan::Command::HelpCommand < Trepan::Command
5
5
 
6
6
  unless defined?(HELP)
7
- HELP =
8
- "help [command [subcommand]|expression]
7
+ NAME = File.basename(__FILE__, '.rb')
8
+ HELP = <<-HELP
9
+ #{NAME} [command [subcommand]|expression]
9
10
 
10
11
  Without argument, print the list of available debugger commands.
11
12
 
@@ -22,8 +23,7 @@ subcommand. For example 'help info line' give help about the
22
23
  info line command.
23
24
 
24
25
  See also 'examine' and 'whatis'.
25
- "
26
-
26
+ HELP
27
27
 
28
28
  ALIASES = %w(?)
29
29
  CATEGORIES = {
@@ -36,20 +36,21 @@ See also 'examine' and 'whatis'.
36
36
  'stack' => 'Examining the call stack'
37
37
  }
38
38
  CATEGORY = 'support'
39
- NAME = File.basename(__FILE__, '.rb')
40
39
  NEED_STACK = false
41
40
  SHORT_HELP = 'Print commands or give help for command(s)'
42
41
  end
43
42
 
44
43
  # List the command categories and a short description of each.
45
44
  def list_categories
46
- msg("Classes of commands:")
45
+ section 'Classes of commands:'
47
46
  CATEGORIES.keys.sort.each do |cat|
48
47
  msg("%-13s -- %s" % [cat, CATEGORIES[cat]])
49
48
  end
50
49
  final_msg = '
51
50
  Type "help" followed by a class name for a list of commands in that class.
51
+ Type "help syntax" for information on debugger command syntax.
52
52
  Type "help *" for the list of all commands.
53
+ Type "help all" for the list of all commands.
53
54
  Type "help REGEXP" for the list of commands matching /^#{REGEXP}/
54
55
  Type "help CLASS *" for the list of all commands in class CLASS.
55
56
  Type "help" followed by command name for full documentation.
@@ -62,8 +63,14 @@ Type "help" followed by command name for full documentation.
62
63
  if args.size > 1
63
64
  cmd_name = args[1]
64
65
  if cmd_name == '*'
65
- msg("All command names:")
66
+ section 'All command names:'
66
67
  msg columnize_commands(@proc.commands.keys.sort)
68
+ elsif cmd_name =~ /^syntax$/i
69
+ show_command_syntax
70
+ elsif cmd_name =~ /^all$/i
71
+ CATEGORIES.sort.each do |category|
72
+ show_category(category[0], [])
73
+ end
67
74
  elsif CATEGORIES.member?(cmd_name)
68
75
  show_category(args[1], args[2..-1])
69
76
  elsif @proc.commands.member?(cmd_name) or @proc.aliases.member?(cmd_name)
@@ -84,42 +91,87 @@ Type "help" followed by command name for full documentation.
84
91
  msg "Aliases: #{cmd_obj.class.const_get(:ALIASES).join(', ')}"
85
92
  end
86
93
  end
87
- else
94
+ else
88
95
  matches = @proc.commands.keys.grep(/^#{cmd_name}/).sort rescue []
89
96
  if matches.empty?
90
97
  errmsg("No commands found matching /^#{cmd_name}/. Try \"help\".")
91
98
  else
92
- msg("Command names matching /^#{cmd_name}/:")
99
+ section "Command names matching /^#{cmd_name}/:"
93
100
  msg columnize_commands(matches.sort)
94
101
  end
95
102
  end
96
103
  else
97
104
  list_categories
98
105
  end
99
- return false # Don't break out of cmd loop
100
106
  end
101
107
 
102
108
  # Show short help for all commands in `category'.
103
109
  def show_category(category, args)
104
110
 
105
111
  if args.size == 1 && args[0] == '*'
106
- msg("Commands in class %s:" % category)
112
+ section "Commands in class %s:" % category
107
113
 
108
114
  cmds = @proc.commands.keys.select do |cmd_name|
109
115
  category == @proc.commands[cmd_name].category
110
116
  end.sort
111
-
112
117
  width = settings[:maxwidth]
113
118
  return columnize_commands(cmds)
114
119
  end
115
120
 
116
- msg("%s." % CATEGORIES[category])
117
- msg("List of commands:\n")
121
+ msg('')
122
+ section "Command class: %s" % category
123
+ msg('')
118
124
  @proc.commands.keys.sort.each do |name|
119
125
  next if category != @proc.commands[name].category
120
126
  msg("%-13s -- %s" % [name, @proc.commands[name].short_help])
121
127
  end
122
128
  end
129
+
130
+ def show_command_syntax
131
+ section "Debugger command syntax"
132
+ msg <<-EOS
133
+ Command command syntax is very simple-minded.
134
+
135
+ If a line starts with #, the command is ignored.
136
+ If a line starts with !, the line is eval'd.
137
+
138
+ If the command you want eval'd uses the Ruby ! initally, add that
139
+ after the first !.
140
+
141
+ Commands are split at whereever ;; appears. This process disregards
142
+ any quotes or other symbols that have meaning in Ruby. The strings
143
+ after the leading command string are put back on a command queue.
144
+
145
+ Within a single command, tokens are then white-space split. Again,
146
+ this process disregards quotes or symbols that have meaning in Ruby.
147
+
148
+ The first token is then looked up in the debugger command table and
149
+ then the debugger alias table. If a match is found the command name
150
+ and arguments are dispatched to the command object that process the
151
+ command.
152
+
153
+ If the command is not found and "auto eval" is set on, then the
154
+ command is eval'd in the context that the program is currently stopped
155
+ at. If "auto eval" is not set on, then we display an error message
156
+ that the entered string is "undefined".
157
+
158
+ If you want irb-like command-processing, it's possible to go into an
159
+ irb shell with the "irb" command. It is also possible to arrange going
160
+ into an irb shell every time you enter the debugger.
161
+
162
+ Examples:
163
+
164
+ # This line does nothing. It is a comment
165
+ s # by default, this is an alias for the "step" command
166
+ !s # shows the value of variable step.
167
+ !!s # Evaluates !s (or "not s"). The first ! is indicates evaluate.
168
+ info program;; list # Runs two commands "info program" and "list"
169
+ pr "hi ;;-)" # Syntax error since ;; splits the line and " is not closed.
170
+ !puts "hi ;;-)" # One way to do the above.
171
+
172
+ See also "alias", "irb", "set auto eval", and "set auto irb".
173
+ EOS
174
+ end
123
175
  end
124
176
 
125
177
  if __FILE__ == $0
@@ -129,16 +181,15 @@ if __FILE__ == $0
129
181
 
130
182
  cmd.run %W(#{cmd.name} help)
131
183
  puts '=' * 40
132
- cmd.run %w(#{cmd.name} *)
184
+ cmd.run %W(#{cmd.name} *)
133
185
  puts '=' * 40
134
- cmd.run %w(#{cmd.name} fdafsasfda)
186
+ cmd.run %W(#{cmd.name} fdafsasfda)
135
187
  puts '=' * 40
136
188
  cmd.run [cmd.name]
137
189
  puts '=' * 40
138
190
  cmd.run %W(#{cmd.name} support)
139
191
  puts '=' * 40
140
192
  cmd.run %W(#{cmd.name} support *)
141
-
142
193
  puts '=' * 40
143
194
  cmd.run %W(#{cmd.name} s.*)
144
195
  puts '=' * 40
@@ -1,9 +1,12 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
1
3
  require 'rubygems'; require 'require_relative'
2
4
  require_relative '../base/subcmd'
3
5
 
4
6
  class Trepan::Subcommand::InfoBreakpoints < Trepan::Subcommand
7
+ Trepanning::Subcommand.set_name_prefix(__FILE__, self)
5
8
  HELP = <<-EOH
6
- info breakpoints [num1 ...] [verbose]
9
+ #{PREFIX.join(' ')} [num1 ...] [verbose]
7
10
 
8
11
  Show status of user-settable breakpoints. If no breakpoint numbers are
9
12
  given, the show all breakpoints. Otherwise only those breakpoints
@@ -18,15 +21,9 @@ The "enb" column indicates whether the breakpoint is enabled.
18
21
  The "Where" column indicates where the breakpoint is located.
19
22
  EOH
20
23
  MIN_ABBREV = 'br'.size
21
- NAME = File.basename(__FILE__, '.rb')
22
- PREFIX = %w(info breakpoints)
23
24
  SHORT_HELP = 'Status of user-settable breakpoints'
24
25
 
25
26
  def run(args)
26
- # FIXME: Originally was
27
- # section "Breakpoints"
28
- # Add section?
29
-
30
27
  show_all =
31
28
  if args.size > 2
32
29
  opts = {
@@ -46,10 +43,11 @@ EOH
46
43
  msg('No breakpoints.')
47
44
  else
48
45
  # There's at least one
46
+ section "Num Breakpoint"
49
47
  bpmgr.list.each do |bp|
50
48
  msg "%3d: %s" % [bp.id, bp.describe]
51
49
  end
52
- msg('Deferred breakpoints...')
50
+ section 'Deferred breakpoints...'
53
51
  @proc.dbgr.deferred_breakpoints.each_with_index do |bp, i|
54
52
  if bp
55
53
  msg "%3d: %s" % [i+1, bp.describe]