rbx-trepanning 0.0.1-universal-rubinius

Sign up to get free protection for your applications and to get access to all the features.
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