rbx-trepanning 0.0.1-universal-rubinius

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 (205) hide show
  1. data/ChangeLog +376 -0
  2. data/LICENSE +25 -0
  3. data/NEWS +2 -0
  4. data/README.textile +28 -0
  5. data/Rakefile +165 -0
  6. data/THANKS +14 -0
  7. data/app/breakpoint.rb +218 -0
  8. data/app/breakpoint.rbc +3564 -0
  9. data/app/brkptmgr.rb +138 -0
  10. data/app/brkptmgr.rbc +2827 -0
  11. data/app/default.rb +61 -0
  12. data/app/default.rbc +1011 -0
  13. data/app/display.rb +35 -0
  14. data/app/display.rbc +968 -0
  15. data/app/frame.rb +98 -0
  16. data/app/frame.rbc +1808 -0
  17. data/app/irb.rb +112 -0
  18. data/app/irb.rbc +2111 -0
  19. data/app/iseq.rb +95 -0
  20. data/app/iseq.rbc +1801 -0
  21. data/app/method.rb +173 -0
  22. data/app/method.rbc +2492 -0
  23. data/app/mock.rb +13 -0
  24. data/app/mock.rbc +398 -0
  25. data/app/options.rb +123 -0
  26. data/app/options.rbc +2183 -0
  27. data/app/run.rb +86 -0
  28. data/app/run.rbc +1244 -0
  29. data/app/util.rb +49 -0
  30. data/app/util.rbc +1144 -0
  31. data/app/validate.rb +30 -0
  32. data/app/validate.rbc +676 -0
  33. data/bin/trepan.compiled.rbc +1043 -0
  34. data/bin/trepanx +63 -0
  35. data/bin/trepanx.compiled.rbc +985 -0
  36. data/interface/base_intf.rb +95 -0
  37. data/interface/base_intf.rbc +1742 -0
  38. data/interface/script.rb +104 -0
  39. data/interface/script.rbc +1642 -0
  40. data/interface/user.rb +91 -0
  41. data/interface/user.rbc +1418 -0
  42. data/io/base_io.rb +94 -0
  43. data/io/base_io.rbc +1404 -0
  44. data/io/input.rb +112 -0
  45. data/io/input.rbc +1979 -0
  46. data/io/null_output.rb +42 -0
  47. data/io/null_output.rbc +730 -0
  48. data/io/string_array.rb +156 -0
  49. data/io/string_array.rbc +2466 -0
  50. data/lib/trepanning.rb +398 -0
  51. data/lib/trepanning.rbc +6661 -0
  52. data/processor/breakpoint.rb +161 -0
  53. data/processor/command/alias.rb +55 -0
  54. data/processor/command/backtrace.rb +46 -0
  55. data/processor/command/base/cmd.rb +124 -0
  56. data/processor/command/base/subcmd.rb +213 -0
  57. data/processor/command/base/submgr.rb +179 -0
  58. data/processor/command/base/subsubcmd.rb +103 -0
  59. data/processor/command/base/subsubmgr.rb +184 -0
  60. data/processor/command/break.rb +100 -0
  61. data/processor/command/continue.rb +82 -0
  62. data/processor/command/delete.rb +30 -0
  63. data/processor/command/directory.rb +43 -0
  64. data/processor/command/disassemble.rb +103 -0
  65. data/processor/command/down.rb +54 -0
  66. data/processor/command/eval.rb +31 -0
  67. data/processor/command/exit.rb +58 -0
  68. data/processor/command/finish.rb +78 -0
  69. data/processor/command/frame.rb +89 -0
  70. data/processor/command/help.rb +146 -0
  71. data/processor/command/info.rb +28 -0
  72. data/processor/command/info_subcmd/breakpoints.rb +75 -0
  73. data/processor/command/info_subcmd/file.rb +153 -0
  74. data/processor/command/info_subcmd/method.rb +71 -0
  75. data/processor/command/info_subcmd/program.rb +59 -0
  76. data/processor/command/info_subcmd/variables.rb +40 -0
  77. data/processor/command/irb.rb +96 -0
  78. data/processor/command/kill.rb +70 -0
  79. data/processor/command/list.rb +296 -0
  80. data/processor/command/next.rb +66 -0
  81. data/processor/command/nexti.rb +59 -0
  82. data/processor/command/pr.rb +38 -0
  83. data/processor/command/ps.rb +40 -0
  84. data/processor/command/restart.rb +60 -0
  85. data/processor/command/set.rb +47 -0
  86. data/processor/command/set_subcmd/auto.rb +28 -0
  87. data/processor/command/set_subcmd/auto_subcmd/dis.rb +33 -0
  88. data/processor/command/set_subcmd/auto_subcmd/eval.rb +54 -0
  89. data/processor/command/set_subcmd/auto_subcmd/irb.rb +34 -0
  90. data/processor/command/set_subcmd/auto_subcmd/list.rb +34 -0
  91. data/processor/command/set_subcmd/basename.rb +26 -0
  92. data/processor/command/set_subcmd/debug.rb +27 -0
  93. data/processor/command/set_subcmd/debug_subcmd/dbgr.rb +36 -0
  94. data/processor/command/set_subcmd/debug_subcmd/skip.rb +23 -0
  95. data/processor/command/set_subcmd/debug_subcmd/step.rb +23 -0
  96. data/processor/command/set_subcmd/different.rb +60 -0
  97. data/processor/command/set_subcmd/hidelevel.rb +63 -0
  98. data/processor/command/set_subcmd/kernelstep.rb +61 -0
  99. data/processor/command/set_subcmd/max.rb +29 -0
  100. data/processor/command/set_subcmd/max_subcmd/list.rb +49 -0
  101. data/processor/command/set_subcmd/max_subcmd/stack.rb +50 -0
  102. data/processor/command/set_subcmd/max_subcmd/string.rb +54 -0
  103. data/processor/command/set_subcmd/max_subcmd/width.rb +49 -0
  104. data/processor/command/set_subcmd/substitute.rb +25 -0
  105. data/processor/command/set_subcmd/substitute_subcmd/path.rb +56 -0
  106. data/processor/command/set_subcmd/trace.rb +37 -0
  107. data/processor/command/set_subcmd/trace_subcmd/print.rb +57 -0
  108. data/processor/command/show.rb +27 -0
  109. data/processor/command/show_subcmd/alias.rb +43 -0
  110. data/processor/command/show_subcmd/args.rb +26 -0
  111. data/processor/command/show_subcmd/auto.rb +28 -0
  112. data/processor/command/show_subcmd/auto_subcmd/dis.rb +37 -0
  113. data/processor/command/show_subcmd/auto_subcmd/eval.rb +28 -0
  114. data/processor/command/show_subcmd/auto_subcmd/irb.rb +23 -0
  115. data/processor/command/show_subcmd/auto_subcmd/list.rb +22 -0
  116. data/processor/command/show_subcmd/basename.rb +22 -0
  117. data/processor/command/show_subcmd/debug.rb +27 -0
  118. data/processor/command/show_subcmd/debug_subcmd/dbgr.rb +21 -0
  119. data/processor/command/show_subcmd/debug_subcmd/skip.rb +22 -0
  120. data/processor/command/show_subcmd/debug_subcmd/step.rb +22 -0
  121. data/processor/command/show_subcmd/different.rb +27 -0
  122. data/processor/command/show_subcmd/hidelevel.rb +42 -0
  123. data/processor/command/show_subcmd/kernelstep.rb +37 -0
  124. data/processor/command/show_subcmd/max.rb +30 -0
  125. data/processor/command/show_subcmd/max_subcmd/list.rb +38 -0
  126. data/processor/command/show_subcmd/max_subcmd/stack.rb +36 -0
  127. data/processor/command/show_subcmd/max_subcmd/string.rb +42 -0
  128. data/processor/command/show_subcmd/max_subcmd/width.rb +37 -0
  129. data/processor/command/show_subcmd/trace.rb +29 -0
  130. data/processor/command/show_subcmd/trace_subcmd/print.rb +38 -0
  131. data/processor/command/source.rb +83 -0
  132. data/processor/command/step.rb +41 -0
  133. data/processor/command/tbreak.rb +19 -0
  134. data/processor/command/unalias.rb +44 -0
  135. data/processor/command/up.rb +87 -0
  136. data/processor/default.rb +56 -0
  137. data/processor/disassemble.rb +32 -0
  138. data/processor/eval.rb +96 -0
  139. data/processor/frame.rb +211 -0
  140. data/processor/help.rb +72 -0
  141. data/processor/hook.rb +133 -0
  142. data/processor/load_cmds.rb +101 -0
  143. data/processor/location.rb +128 -0
  144. data/processor/main.rb +394 -0
  145. data/processor/mock.rb +137 -0
  146. data/processor/msg.rb +28 -0
  147. data/processor/running.rb +230 -0
  148. data/processor/stepping.rb +115 -0
  149. data/processor/subcmd.rb +160 -0
  150. data/processor/validate.rb +355 -0
  151. data/test/data/enable.right +36 -0
  152. data/test/data/fname-with-blank.cmd +6 -0
  153. data/test/data/fname-with-blank.right +1 -0
  154. data/test/data/quit-Xdebug.right +3 -0
  155. data/test/data/quit.cmd +5 -0
  156. data/test/data/quit.right +0 -0
  157. data/test/example/fname with blank.rb +1 -0
  158. data/test/example/gcd-xx.rb +18 -0
  159. data/test/example/gcd.rb +19 -0
  160. data/test/example/gcd1.rb +24 -0
  161. data/test/example/null.rb +1 -0
  162. data/test/example/thread1.rb +3 -0
  163. data/test/functional/fn_helper.rb +112 -0
  164. data/test/functional/test-break-name.rb +52 -0
  165. data/test/functional/test-break.rb +51 -0
  166. data/test/functional/test-finish.rb +70 -0
  167. data/test/functional/test-fn_helper.rb +43 -0
  168. data/test/functional/test-list.rb +55 -0
  169. data/test/functional/test-next-bug.rb +49 -0
  170. data/test/functional/test-next.rb +101 -0
  171. data/test/functional/test-step.rb +272 -0
  172. data/test/functional/test-step2.rb +35 -0
  173. data/test/functional/test-tbreak.rb +41 -0
  174. data/test/integration/file-diff.rb +89 -0
  175. data/test/integration/helper.rb +78 -0
  176. data/test/integration/test-fname-with-blank.rb +12 -0
  177. data/test/integration/test-quit.rb +25 -0
  178. data/test/unit/cmd-helper.rb +46 -0
  179. data/test/unit/test-app-brkpt.rb +30 -0
  180. data/test/unit/test-app-brkptmgr.rb +51 -0
  181. data/test/unit/test-app-iseq.rb +49 -0
  182. data/test/unit/test-app-method.rb +54 -0
  183. data/test/unit/test-app-options.rb +61 -0
  184. data/test/unit/test-app-run.rb +16 -0
  185. data/test/unit/test-app-util.rb +28 -0
  186. data/test/unit/test-app-validate.rb +18 -0
  187. data/test/unit/test-base-subcmd.rb +61 -0
  188. data/test/unit/test-bin-trepanx.rb +48 -0
  189. data/test/unit/test-cmd-alias.rb +49 -0
  190. data/test/unit/test-cmd-break.rb +23 -0
  191. data/test/unit/test-cmd-exit.rb +27 -0
  192. data/test/unit/test-cmd-help.rb +101 -0
  193. data/test/unit/test-cmd-kill.rb +48 -0
  194. data/test/unit/test-intf-user.rb +46 -0
  195. data/test/unit/test-io-input.rb +27 -0
  196. data/test/unit/test-proc-eval.rb +37 -0
  197. data/test/unit/test-proc-frame.rb +79 -0
  198. data/test/unit/test-proc-help.rb +16 -0
  199. data/test/unit/test-proc-hook.rb +30 -0
  200. data/test/unit/test-proc-load_cmds.rb +41 -0
  201. data/test/unit/test-proc-location.rb +48 -0
  202. data/test/unit/test-proc-main.rb +96 -0
  203. data/test/unit/test-proc-validate.rb +91 -0
  204. data/test/unit/test-subcmd-help.rb +51 -0
  205. metadata +337 -0
@@ -0,0 +1,43 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require 'rubygems'; require 'require_relative'
3
+ require_relative 'base/cmd'
4
+ class Trepan::Command::DirectoryCommand < Trepan::Command
5
+
6
+ unless defined?(HELP)
7
+ ALIASES = %w(dir)
8
+ CATEGORY = 'files'
9
+ MAX_ARGS = 1 # Need at most this many
10
+ NAME = File.basename(__FILE__, '.rb')
11
+ HELP = <<-HELP
12
+ Add directory DIR to beginning of search path for source files.
13
+ DIR can also be $cwd for the current working directory, or $cdir for the
14
+ directory in which the debugged file start.
15
+ With no argument, reset the search path to $cdir:$cwd, the default.
16
+
17
+ This command may be useful for debugging into Rubinius methods such as
18
+ kernel/common/module.rb if have the source code somewhere.
19
+ HELP
20
+ SHORT_HELP =
21
+ 'Add directory DIR to beginning of search path for source files'
22
+ end
23
+
24
+ # This method runs the command
25
+ def run(args) # :nodoc
26
+ if args.size > 1
27
+ settings[:directory] = "#{args[1]}:#{settings[:directory]}"
28
+ msg "Source directories searched: #{settings[:directory]}"
29
+ else
30
+ if confirm('Reintialize source path to empty?', false)
31
+ settings[:directory] = '$cdir:$cwd'
32
+ msg 'Source directories searched: $cdir:$cwd'
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ if __FILE__ == $0
39
+ require_relative '../mock'
40
+ dbgr, cmd = MockDebugger::setup
41
+ cmd.run([cmd.name])
42
+ cmd.run([cmd.name, '/tmp'])
43
+ end
@@ -0,0 +1,103 @@
1
+ require 'rubygems'; require 'require_relative'
2
+ require_relative './base/cmd'
3
+ require_relative '../../app/iseq'
4
+
5
+ class Trepan::Command::DisassembleCommand < Trepan::Command
6
+ NAME = File.basename(__FILE__, '.rb')
7
+ ALIASES = %w(dis)
8
+ CATEGORY = 'data'
9
+ HELP = <<-HELP
10
+ #{NAME} [all|method]
11
+
12
+ Disassembles Rubinius VM instructions. By default, the bytecode for the
13
+ current line is disassembled only.
14
+
15
+ If a method name is given, disassemble just that method. If the
16
+ argument is 'all', the entire method is shown as bytecode.
17
+
18
+ Examples:
19
+ #{NAME} # dissasemble VM for current line
20
+ #{NAME} all # disassemble entire current method
21
+ #{NAME} [1,2].max # disassemble max method of Array
22
+ #{NAME} Object.is_a? # disassemble Object.is_a?
23
+ #{NAME} is_a? # same as above (probably)
24
+
25
+ HELP
26
+
27
+ NEED_STACK = true
28
+ SHORT_HELP = 'Show the bytecode for the current method'
29
+
30
+ def disassemble_method(cm)
31
+ frame_ip = (@proc.frame.method == cm) ? @proc.frame.next_ip : nil
32
+ lines = cm.lines
33
+ next_line_ip = 0
34
+ next_i = 1
35
+ cm.decode.each do |insn|
36
+ show_line =
37
+ if insn.ip >= next_line_ip
38
+ next_line_ip = lines.at(next_i+1)
39
+ line_no = lines.at(next_i)
40
+ next_i += 2
41
+ true
42
+ else
43
+ false
44
+ end
45
+
46
+ prefix = Trepanning::ISeq::disasm_prefix(insn.ip, frame_ip, cm)
47
+ str = "#{prefix} #{insn}"
48
+ if show_line
49
+ str +=
50
+ if insn.instance_variable_get('@comment')
51
+ ' '
52
+ elsif str[-1..-1] !~/\s/
53
+ ' '
54
+ else
55
+ ''
56
+ end
57
+ str += "# line: #{line_no}"
58
+ end
59
+ msg str
60
+ end
61
+ end
62
+
63
+ # Run command.
64
+ def run(args)
65
+ if 1 == args.size
66
+ @proc.show_bytecode
67
+ elsif 'all' == args[1]
68
+ # FIXME: first msg is a section command.
69
+ msg "Bytecode for #{@proc.frame.vm_location.describe}"
70
+ disassemble_method(current_method)
71
+ else
72
+ cm = @proc.parse_method(args[1])
73
+ if cm
74
+ # FIXME: first msg is a section command.
75
+ msg "Bytecode for method #{args[1]}"
76
+ disassemble_method(cm.executable)
77
+ else
78
+ errmsg "Method #{args[1]} not found"
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ if __FILE__ == $0
85
+ # Demo it.
86
+ require_relative '../mock'
87
+ dbgr, cmd = MockDebugger::setup
88
+ def foo(cmd)
89
+ puts "#{cmd.name}"
90
+ cmd.run([cmd.name])
91
+ puts '=' * 40
92
+ puts "#{cmd.name} all"
93
+ cmd.run([cmd.name, 'all'])
94
+ puts '=' * 40
95
+ p cmd.proc.frame.vm_location.describe
96
+ cmd.run([cmd.name, 'foo'])
97
+ puts '=' * 40
98
+ # require_relative '../../lib/trepanning'
99
+ # debugger
100
+ cmd.run([cmd.name, 'self.setup'])
101
+ end
102
+ foo(cmd)
103
+ end
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative 'up'
5
+
6
+ # Debugger "down" command. Is the same as the "up" command with the
7
+ # direction (set by DIRECTION) reversed.
8
+ class Trepan::Command::DownCommand < Trepan::Command::UpCommand
9
+
10
+ # Silence already initialized constant .. warnings
11
+ old_verbose = $VERBOSE
12
+ $VERBOSE = nil
13
+ HELP =
14
+ "d(own) [count]
15
+
16
+ Move the current frame down in the stack trace (to a newer frame). 0
17
+ is the most recent frame. If no count is given, move down 1.
18
+
19
+ See also 'up' and 'frame'.
20
+ "
21
+
22
+ ALIASES = %w(d)
23
+ NAME = File.basename(__FILE__, '.rb')
24
+ SHORT_HELP = 'Move frame in the direction of the caller of the last-selected frame'
25
+ $VERBOSE = old_verbose
26
+
27
+ def initialize(proc)
28
+ super
29
+ @direction = -1 # +1 for up.
30
+ end
31
+
32
+ end
33
+
34
+ if __FILE__ == $0
35
+ # Demo it.
36
+ require_relative '../mock'
37
+ dbgr, cmd = MockDebugger::setup
38
+
39
+ # def sep ; puts '=' * 40 end
40
+ # cmd.run [cmd.name]
41
+ # %w(-1 0 1 -2).each do |count|
42
+ # puts "#{cmd.name} #{count}"
43
+ # cmd.run([cmd.name, count])
44
+ # sep
45
+ # end
46
+ # def foo(cmd, cmd.name)
47
+ # puts "#{cmd.name}"
48
+ # cmd.run([cmd.name])
49
+ # sep
50
+ # puts "#{cmd.name} -1"
51
+ # cmd.run([cmd.name, '-1'])
52
+ # end
53
+ # foo(cmd, cmd.name)
54
+ end
@@ -0,0 +1,31 @@
1
+ require 'rubygems'; require 'require_relative'
2
+ require_relative './base/cmd'
3
+
4
+ class Trepan::Command::EvalCommand < Trepan::Command
5
+
6
+ CATEGORY = 'data'
7
+ HELP = <<-HELP
8
+ Run code in the context of the current frame.
9
+
10
+ The value of the expression is stored into a global variable so it
11
+ may be used again easily. The name of the global variable is printed
12
+ next to the inspect output of the value.
13
+ HELP
14
+
15
+ NAME = File.basename(__FILE__, '.rb')
16
+ NEED_STACK = true
17
+ SHORT_HELP = 'Run code in the current context'
18
+ def run(args)
19
+ @proc.debug_eval(@proc.cmd_argstr, @proc.settings[:maxstring])
20
+ end
21
+ end
22
+
23
+ if __FILE__ == $0
24
+ require_relative '../mock'
25
+ dbgr, cmd = MockDebugger::setup
26
+ arg_str = '1 + 2'
27
+ ## cmd.proc.instance_variable_set('@cmd_argstr', arg_str)
28
+ dbgr.instance_variable_set('@cmd_argstr', arg_str)
29
+
30
+ ## cmd.run([cmd.name, arg_str])
31
+ end
@@ -0,0 +1,58 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require 'rubygems'; require 'require_relative'
3
+ require_relative 'base/cmd'
4
+ class Trepan::Command::ExitCommand < Trepan::Command
5
+
6
+ unless defined?(HELP)
7
+ ALIASES = %w(quit q q! quit! exit!)
8
+ HELP =
9
+ 'exit [exitcode] - hard exit of the debugged program.
10
+
11
+ The program being debugged is exited via exit!() which does not run
12
+ the Kernel at_exit finalizers. If a return code is given, that is the
13
+ return code passed to exit() - presumably the return code that will be
14
+ passed back to the OS. If no exit code is given, 0 is used.
15
+
16
+ If you are in interactive mode, you are prompted to confirm
17
+ quitting. However if you do not want to be prompted, add ! the end.
18
+ (vim/vi/ed users can use alias q!).
19
+
20
+ See also "kill".'
21
+
22
+ CATEGORY = 'support'
23
+ MAX_ARGS = 2 # Need at most this many
24
+ NAME = File.basename(__FILE__, '.rb')
25
+ SHORT_HELP = 'Exit program via "exit!()"'
26
+ end
27
+
28
+ # FIXME: Combine 'quit' and 'exit'. The only difference is
29
+ # whether exit! or exit is used.
30
+
31
+ # This method runs the command
32
+ def run(args) # :nodoc
33
+ unconditional =
34
+ if args.size > 1 && args[1] == 'unconditionally'
35
+ args.shift
36
+ true
37
+ elsif args[0][-1..-1] == '!'
38
+ true
39
+ else
40
+ false
41
+ end
42
+ unless unconditional || confirm('Really quit?', false)
43
+ msg('Quit not confirmed.')
44
+ return
45
+ end
46
+ exitrc = (args.size > 1) ? exitrc = Integer(args[1]) rescue 0 : 0
47
+ # No graceful way to stop threads...
48
+ # A little harsh, but for now let's go with this.
49
+ exit! exitrc
50
+ end
51
+ end
52
+
53
+ if __FILE__ == $0
54
+ require_relative '../mock'
55
+ dbgr, cmd = MockDebugger::setup
56
+ fork { cmd.run([cmd.name]) }
57
+ cmd.run([cmd.name, '10'])
58
+ end
@@ -0,0 +1,78 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative 'base/cmd'
5
+
6
+ class Trepan::Command::FinishCommand < Trepan::Command
7
+
8
+ unless defined?(HELP)
9
+ NAME = File.basename(__FILE__, '.rb')
10
+ HELP = <<-HELP
11
+ #{NAME} [levels]
12
+
13
+ Continue execution until leaving the current function.
14
+ Sometimes this is called 'step out'.
15
+
16
+ When `levels' is specified, that many frame levels need to be
17
+ popped. The default is 1. Note that 'yield' and exceptions raised my
18
+ reduce the number of stack frames. Also, if a thread is switched, we
19
+ stop ignoring levels.
20
+
21
+ 'next>' is similar in that it stops at a return, but it doesn't
22
+ guarantee the stack level is the same as or less than the current
23
+ one.
24
+
25
+ See the break command if you want to stop at a particular point in a
26
+ program. In general, '#{NAME}', 'step' and 'next' may slow a program down
27
+ while 'break' will have less overhead.
28
+ HELP
29
+ ALIASES = %w(fin)
30
+ CATEGORY = 'running'
31
+ # execution_set = ['Running']
32
+ MAX_ARGS = 1 # Need at most this many.
33
+ NEED_STACK = true
34
+ SHORT_HELP = 'Step to end of current method (step out)'
35
+ end
36
+
37
+ # This method runs the command
38
+ def run(args) # :nodoc
39
+ opts = {}
40
+ if args.size == 1
41
+ # Form is: "finish" which means "finish 1"
42
+ level_count = 0
43
+ else
44
+ count_str = args[1]
45
+ opts = {
46
+ :msg_on_error =>
47
+ "The '#{NAME}' command argument must eval to an integer. Got: %s" %
48
+ count_str,
49
+ :min_value => 1
50
+ }
51
+ count = @proc.get_an_int(count_str, opts)
52
+ return unless count
53
+ # step 1 is core.level_count = 0 or "stop next event"
54
+ level_count = count - 1
55
+ end
56
+ if 0 == level_count and %w(return c-return).member?(@proc.event)
57
+ errmsg "You are already at the requested return event."
58
+ else
59
+ @proc.finish(level_count, opts)
60
+ end
61
+ end
62
+ end
63
+
64
+ if __FILE__ == $0
65
+ require_relative '../mock'
66
+ dbgr, cmd = MockDebugger::setup
67
+ [%W(#{cmd.name} 1), %w(fin 2-1), %w(n foo)].each do |c|
68
+ cmd.proc.leave_cmd_loop = false
69
+ result = cmd.run(c)
70
+ puts 'Run result: %s' % result
71
+ puts 'leave_cmd_loop: %s' % cmd.proc.leave_cmd_loop
72
+ end
73
+ [%w(fin), [cmd.name]].each do |c|
74
+ cmd.proc.leave_cmd_loop = false
75
+ result = cmd.run(c)
76
+ puts cmd.proc.different_pos
77
+ end
78
+ end
@@ -0,0 +1,89 @@
1
+ require 'rubygems'; require 'require_relative'
2
+ require_relative './base/cmd'
3
+
4
+ class Trepan::Command::FrameCommand < Trepan::Command
5
+ CATEGORY = 'stack'
6
+ HELP = <<-HELP
7
+ frame [frame-number]
8
+
9
+ Change the current frame to frame `frame-number' if specified, or the
10
+ most-recent frame, 0, if no frame number specified.
11
+
12
+ A negative number indicates the position from the other or
13
+ least-recently-entered end. So 'frame -1' moves to the oldest frame.
14
+ Any variable or expression that evaluates to a number can be used as a
15
+ position, however due to parsing limitations, the position expression
16
+ has to be seen as a single blank-delimited parameter. That is, the
17
+ expression '(5*3)-1' is okay while '( (5 * 3) - 1 )' isn't.
18
+
19
+ Examples:
20
+ frame # Set current frame at the current stopping point
21
+ frame 0 # Same as above
22
+ frame 5-5 # Same as above. Note: no spaces allowed in expression 5-5
23
+ frame 1 # Move to frame 1. Same as: frame 0; up
24
+ frame -1 # The least-recent frame
25
+
26
+ See also 'up', 'down', and 'backtrace'.
27
+ HELP
28
+ NAME = File.basename(__FILE__, '.rb')
29
+ SHORT_HELP = 'Make a specific frame in the call stack the current frame'
30
+
31
+ def run(args)
32
+
33
+ if args.size == 1
34
+ # Form is: "frame" which means "frame 0"
35
+ position_str = '0'
36
+ elsif args.size == 2
37
+ # Form is: "frame position"
38
+ position_str = args[1]
39
+ # elsif args.size == 3
40
+ # # Form is: frame <position> <thread>
41
+ # name_or_id = args[1]
42
+ # thread_str = args[2]
43
+ # th = @proc.get_thread_from_string(thread_str)
44
+ # if th
45
+ # @proc.frame_setup(th.threadframe)
46
+ # return
47
+ # else
48
+ # # FIXME: Give suitable error message was given
49
+ # end
50
+ # else
51
+ # # Form should be: "frame thread" which means
52
+ # # "frame thread 0"
53
+ # position_str = '0'
54
+ # ## FIXME:
55
+ # ## @proc.find_and_set_debugged_frame(frame, thread_id)
56
+ end
57
+
58
+ stack_size = @proc.dbgr.vm_locations.size
59
+ if stack_size == 0
60
+ errmsg('No frames recorded.')
61
+ return false
62
+ end
63
+ opts={
64
+ :msg_on_error =>
65
+ "The '#{NAME}' command requires a frame number. Got: #{position_str}",
66
+ :min_value => -stack_size,
67
+ :max_value => stack_size-1
68
+ }
69
+ frame_num = @proc.get_an_int(position_str, opts)
70
+ return false unless frame_num
71
+
72
+ @proc.adjust_frame(frame_num, true)
73
+ return true
74
+ end
75
+ end
76
+
77
+ if __FILE__ == $0
78
+ # Demo it.
79
+ require_relative '../mock'
80
+ dbgr, cmd = MockDebugger::setup
81
+
82
+ # def sep ; puts '=' * 40 end
83
+ # %w(0 1 -2).each {|count| cmd.run([cmd.name, count]); sep }
84
+ # def foo(cmd, cmd.name)
85
+ # cmd.proc.frame_setup(RubyVM::ThreadFrame::current)
86
+ # %w(0 -1).each {|count| cmd.run([cmd.name, count]); sep }
87
+ # end
88
+ # foo(cmd, cmd.name)
89
+ end
@@ -0,0 +1,146 @@
1
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require 'rubygems'; require 'require_relative'
3
+ require_relative 'base/cmd'
4
+ class Trepan::Command::HelpCommand < Trepan::Command
5
+
6
+ unless defined?(HELP)
7
+ HELP =
8
+ "help [command [subcommand]|expression]
9
+
10
+ Without argument, print the list of available debugger commands.
11
+
12
+ When an argument is given, it is first checked to see if it is command
13
+ name. 'help where' gives help on the 'where' debugger command.
14
+
15
+ If the environment variable $PAGER is defined, the file is
16
+ piped through that command. You'll notice this only for long help
17
+ output.
18
+
19
+ Some commands like 'info', 'set', and 'show' can accept an
20
+ additional subcommand to give help just about that particular
21
+ subcommand. For example 'help info line' give help about the
22
+ info line command.
23
+
24
+ See also 'examine' and 'whatis'.
25
+ "
26
+
27
+
28
+ ALIASES = %w(?)
29
+ CATEGORIES = {
30
+ 'breakpoints' => 'Making the program stop at certain points',
31
+ 'data' => 'Examining data',
32
+ 'files' => 'Specifying and examining files',
33
+ 'running' => 'Running the program',
34
+ 'status' => 'Status inquiries',
35
+ 'support' => 'Support facilities',
36
+ 'stack' => 'Examining the call stack'
37
+ }
38
+ CATEGORY = 'support'
39
+ NAME = File.basename(__FILE__, '.rb')
40
+ NEED_STACK = false
41
+ SHORT_HELP = 'Print commands or give help for command(s)'
42
+ end
43
+
44
+ # List the command categories and a short description of each.
45
+ def list_categories
46
+ msg("Classes of commands:")
47
+ CATEGORIES.keys.sort.each do |cat|
48
+ msg("%-13s -- %s" % [cat, CATEGORIES[cat]])
49
+ end
50
+ final_msg = '
51
+ Type "help" followed by a class name for a list of commands in that class.
52
+ Type "help *" for the list of all commands.
53
+ Type "help REGEXP" for the list of commands matching /^#{REGEXP}/
54
+ Type "help CLASS *" for the list of all commands in class CLASS.
55
+ Type "help" followed by command name for full documentation.
56
+ '
57
+ msg(final_msg)
58
+ end
59
+
60
+ # This method runs the command
61
+ def run(args) # :nodoc
62
+ if args.size > 1
63
+ cmd_name = args[1]
64
+ if cmd_name == '*'
65
+ msg("All command names:")
66
+ msg columnize_commands(@proc.commands.keys.sort)
67
+ elsif CATEGORIES.member?(cmd_name)
68
+ show_category(args[1], args[2..-1])
69
+ elsif @proc.commands.member?(cmd_name) or @proc.aliases.member?(cmd_name)
70
+ real_name =
71
+ if @proc.commands.member?(cmd_name)
72
+ cmd_name
73
+ else
74
+ @proc.aliases[cmd_name]
75
+ end
76
+ cmd_obj = @proc.commands[real_name]
77
+ help_text =
78
+ cmd_obj.respond_to?(:help) ? cmd_obj.help(args) :
79
+ cmd_obj.class.const_get(:HELP)
80
+ if help_text
81
+ msg(help_text)
82
+ if cmd_obj.class.constants.member?('ALIASES') and
83
+ args.size == 2
84
+ msg "Aliases: #{cmd_obj.class.const_get(:ALIASES).join(', ')}"
85
+ end
86
+ end
87
+ else
88
+ matches = @proc.commands.keys.grep(/^#{cmd_name}/).sort rescue []
89
+ if matches.empty?
90
+ errmsg("No commands found matching /^#{cmd_name}/. Try \"help\".")
91
+ else
92
+ msg("Command names matching /^#{cmd_name}/:")
93
+ msg columnize_commands(matches.sort)
94
+ end
95
+ end
96
+ else
97
+ list_categories
98
+ end
99
+ return false # Don't break out of cmd loop
100
+ end
101
+
102
+ # Show short help for all commands in `category'.
103
+ def show_category(category, args)
104
+
105
+ if args.size == 1 && args[0] == '*'
106
+ msg("Commands in class %s:" % category)
107
+
108
+ cmds = @proc.commands.keys.select do |cmd_name|
109
+ category == @proc.commands[cmd_name].category
110
+ end.sort
111
+
112
+ width = settings[:maxwidth]
113
+ return columnize_commands(cmds)
114
+ end
115
+
116
+ msg("%s." % CATEGORIES[category])
117
+ msg("List of commands:\n")
118
+ @proc.commands.keys.sort.each do |name|
119
+ next if category != @proc.commands[name].category
120
+ msg("%-13s -- %s" % [name, @proc.commands[name].short_help])
121
+ end
122
+ end
123
+ end
124
+
125
+ if __FILE__ == $0
126
+ # Demo it.
127
+ require_relative '../mock'
128
+ dbgr, cmd = MockDebugger::setup
129
+
130
+ cmd.run %W(#{cmd.name} help)
131
+ puts '=' * 40
132
+ cmd.run %w(#{cmd.name} *)
133
+ puts '=' * 40
134
+ cmd.run %w(#{cmd.name} fdafsasfda)
135
+ puts '=' * 40
136
+ cmd.run [cmd.name]
137
+ puts '=' * 40
138
+ cmd.run %W(#{cmd.name} support)
139
+ puts '=' * 40
140
+ cmd.run %W(#{cmd.name} support *)
141
+
142
+ puts '=' * 40
143
+ cmd.run %W(#{cmd.name} s.*)
144
+ puts '=' * 40
145
+ cmd.run %W(#{cmd.name} s<>)
146
+ end
@@ -0,0 +1,28 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative 'base/submgr'
5
+
6
+ class Trepan::Command::InfoCommand < Trepan::SubcommandMgr
7
+ unless defined?(HELP)
8
+ HELP =
9
+ 'Generic command for showing things about the program being debugged.
10
+
11
+ You can give unique prefix of the name of a subcommand to get
12
+ information about just that subcommand.
13
+
14
+ Type "info" for a list of "info" subcommands and what they do.
15
+ Type "help info *" for just a list of "info" subcommands.
16
+ '
17
+
18
+ ALIASES = %w(i)
19
+ CATEGORY = 'status'
20
+ NAME = File.basename(__FILE__, '.rb')
21
+ SHORT_HELP = 'Information about debugged program and its environment'
22
+ end
23
+ end
24
+
25
+ if __FILE__ == $0
26
+ require_relative '../mock'
27
+ dbgr, cmd = MockDebugger::setup
28
+ end