rbx-trepanning 0.2.0-universal-rubinius-2.0

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 (312) hide show
  1. data/.gitignore +7 -0
  2. data/ChangeLog +2967 -0
  3. data/LICENSE +25 -0
  4. data/Makefile +13 -0
  5. data/NEWS +105 -0
  6. data/README.textile +34 -0
  7. data/Rakefile +244 -0
  8. data/THANKS +14 -0
  9. data/app/.gitignore +2 -0
  10. data/app/breakpoint.rb +242 -0
  11. data/app/brkptmgr.rb +153 -0
  12. data/app/client.rb +71 -0
  13. data/app/cmd_parse.kpeg +242 -0
  14. data/app/cmd_parse.rb +209 -0
  15. data/app/cmd_parser.rb +2083 -0
  16. data/app/complete.rb +79 -0
  17. data/app/condition.rb +22 -0
  18. data/app/default.rb +71 -0
  19. data/app/display.rb +186 -0
  20. data/app/eventbuffer.rb +147 -0
  21. data/app/file.rb +24 -0
  22. data/app/frame.rb +120 -0
  23. data/app/irb.rb +113 -0
  24. data/app/iseq.rb +188 -0
  25. data/app/method.rb +178 -0
  26. data/app/mock.rb +13 -0
  27. data/app/options.rb +154 -0
  28. data/app/rbx-llvm.rb +163 -0
  29. data/app/run.rb +92 -0
  30. data/app/util.rb +99 -0
  31. data/app/validate.rb +30 -0
  32. data/bin/.gitignore +2 -0
  33. data/bin/trepanx +69 -0
  34. data/data/.gitignore +2 -0
  35. data/data/irbrc +41 -0
  36. data/interface/.gitignore +2 -0
  37. data/interface/client.rb +84 -0
  38. data/interface/comcodes.rb +20 -0
  39. data/interface/script.rb +112 -0
  40. data/interface/server.rb +147 -0
  41. data/interface/user.rb +158 -0
  42. data/interface.rb +109 -0
  43. data/io/.gitignore +3 -0
  44. data/io/input.rb +151 -0
  45. data/io/null_output.rb +46 -0
  46. data/io/string_array.rb +155 -0
  47. data/io/tcpclient.rb +129 -0
  48. data/io/tcpfns.rb +33 -0
  49. data/io/tcpserver.rb +141 -0
  50. data/io.rb +148 -0
  51. data/lib/.gitignore +2 -0
  52. data/lib/trepanning.rb +467 -0
  53. data/processor/.gitignore +3 -0
  54. data/processor/Makefile +7 -0
  55. data/processor/breakpoint.rb +167 -0
  56. data/processor/command/.gitignore +2 -0
  57. data/processor/command/alias.rb +65 -0
  58. data/processor/command/backtrace.rb +68 -0
  59. data/processor/command/base/.gitignore +2 -0
  60. data/processor/command/base/subcmd.rb +226 -0
  61. data/processor/command/base/submgr.rb +185 -0
  62. data/processor/command/base/subsubcmd.rb +125 -0
  63. data/processor/command/base/subsubmgr.rb +196 -0
  64. data/processor/command/break.rb +78 -0
  65. data/processor/command/complete.rb +39 -0
  66. data/processor/command/condition.rb +64 -0
  67. data/processor/command/continue.rb +61 -0
  68. data/processor/command/delete.rb +44 -0
  69. data/processor/command/directory.rb +51 -0
  70. data/processor/command/disable.rb +71 -0
  71. data/processor/command/disassemble.rb +180 -0
  72. data/processor/command/display.rb +84 -0
  73. data/processor/command/down.rb +54 -0
  74. data/processor/command/edit.rb +74 -0
  75. data/processor/command/enable.rb +43 -0
  76. data/processor/command/eval.rb +93 -0
  77. data/processor/command/exit.rb +83 -0
  78. data/processor/command/finish.rb +80 -0
  79. data/processor/command/frame.rb +93 -0
  80. data/processor/command/help/.gitignore +1 -0
  81. data/processor/command/help/README +10 -0
  82. data/processor/command/help/command.txt +58 -0
  83. data/processor/command/help/examples.txt +16 -0
  84. data/processor/command/help/filename.txt +40 -0
  85. data/processor/command/help/location.txt +37 -0
  86. data/processor/command/help/suffixes.txt +17 -0
  87. data/processor/command/help.rb +228 -0
  88. data/processor/command/info.rb +30 -0
  89. data/processor/command/info_subcmd/.gitignore +3 -0
  90. data/processor/command/info_subcmd/breakpoints.rb +103 -0
  91. data/processor/command/info_subcmd/files.rb +219 -0
  92. data/processor/command/info_subcmd/frame.rb +68 -0
  93. data/processor/command/info_subcmd/line.rb +75 -0
  94. data/processor/command/info_subcmd/locals.rb +22 -0
  95. data/processor/command/info_subcmd/macro.rb +62 -0
  96. data/processor/command/info_subcmd/method.rb +71 -0
  97. data/processor/command/info_subcmd/program.rb +51 -0
  98. data/processor/command/info_subcmd/ruby.rb +64 -0
  99. data/processor/command/info_subcmd/source.rb +75 -0
  100. data/processor/command/info_subcmd/stack.rb +25 -0
  101. data/processor/command/info_subcmd/variables.rb +35 -0
  102. data/processor/command/info_subcmd/variables_subcmd/.gitignore +2 -0
  103. data/processor/command/info_subcmd/variables_subcmd/class.rb +42 -0
  104. data/processor/command/info_subcmd/variables_subcmd/constant.rb +42 -0
  105. data/processor/command/info_subcmd/variables_subcmd/globals.rb +69 -0
  106. data/processor/command/info_subcmd/variables_subcmd/instance.rb +42 -0
  107. data/processor/command/info_subcmd/variables_subcmd/locals.rb +80 -0
  108. data/processor/command/kill.rb +79 -0
  109. data/processor/command/list.rb +234 -0
  110. data/processor/command/macro.rb +86 -0
  111. data/processor/command/next.rb +67 -0
  112. data/processor/command/nexti.rb +59 -0
  113. data/processor/command/parsetree.rb +51 -0
  114. data/processor/command/pr.rb +37 -0
  115. data/processor/command/ps.rb +40 -0
  116. data/processor/command/restart.rb +60 -0
  117. data/processor/command/save.rb +58 -0
  118. data/processor/command/server.rb +72 -0
  119. data/processor/command/set.rb +47 -0
  120. data/processor/command/set_subcmd/.gitignore +2 -0
  121. data/processor/command/set_subcmd/abbrev.rb +25 -0
  122. data/processor/command/set_subcmd/auto.rb +33 -0
  123. data/processor/command/set_subcmd/auto_subcmd/.gitignore +2 -0
  124. data/processor/command/set_subcmd/auto_subcmd/dis.rb +33 -0
  125. data/processor/command/set_subcmd/auto_subcmd/eval.rb +53 -0
  126. data/processor/command/set_subcmd/auto_subcmd/irb.rb +33 -0
  127. data/processor/command/set_subcmd/auto_subcmd/list.rb +33 -0
  128. data/processor/command/set_subcmd/basename.rb +25 -0
  129. data/processor/command/set_subcmd/confirm.rb +24 -0
  130. data/processor/command/set_subcmd/debug.rb +26 -0
  131. data/processor/command/set_subcmd/debug_subcmd/.gitignore +2 -0
  132. data/processor/command/set_subcmd/debug_subcmd/dbgr.rb +36 -0
  133. data/processor/command/set_subcmd/debug_subcmd/skip.rb +23 -0
  134. data/processor/command/set_subcmd/debug_subcmd/step.rb +23 -0
  135. data/processor/command/set_subcmd/different.rb +61 -0
  136. data/processor/command/set_subcmd/hidelevel.rb +62 -0
  137. data/processor/command/set_subcmd/highlight.rb +39 -0
  138. data/processor/command/set_subcmd/kernelstep.rb +60 -0
  139. data/processor/command/set_subcmd/max.rb +26 -0
  140. data/processor/command/set_subcmd/max_subcmd/.gitignore +2 -0
  141. data/processor/command/set_subcmd/max_subcmd/list.rb +49 -0
  142. data/processor/command/set_subcmd/max_subcmd/stack.rb +50 -0
  143. data/processor/command/set_subcmd/max_subcmd/string.rb +76 -0
  144. data/processor/command/set_subcmd/max_subcmd/width.rb +49 -0
  145. data/processor/command/set_subcmd/reload.rb +42 -0
  146. data/processor/command/set_subcmd/substitute.rb +24 -0
  147. data/processor/command/set_subcmd/substitute_subcmd/.gitignore +3 -0
  148. data/processor/command/set_subcmd/substitute_subcmd/path.rb +56 -0
  149. data/processor/command/set_subcmd/timer.rb +58 -0
  150. data/processor/command/set_subcmd/trace.rb +37 -0
  151. data/processor/command/set_subcmd/trace_subcmd/.gitignore +2 -0
  152. data/processor/command/set_subcmd/trace_subcmd/buffer.rb +42 -0
  153. data/processor/command/set_subcmd/trace_subcmd/print.rb +41 -0
  154. data/processor/command/shell.rb +131 -0
  155. data/processor/command/show.rb +39 -0
  156. data/processor/command/show_subcmd/.gitignore +3 -0
  157. data/processor/command/show_subcmd/abbrev.rb +20 -0
  158. data/processor/command/show_subcmd/aliases.rb +46 -0
  159. data/processor/command/show_subcmd/args.rb +25 -0
  160. data/processor/command/show_subcmd/auto.rb +28 -0
  161. data/processor/command/show_subcmd/auto_subcmd/.gitignore +3 -0
  162. data/processor/command/show_subcmd/auto_subcmd/dis.rb +37 -0
  163. data/processor/command/show_subcmd/auto_subcmd/eval.rb +24 -0
  164. data/processor/command/show_subcmd/auto_subcmd/irb.rb +23 -0
  165. data/processor/command/show_subcmd/auto_subcmd/list.rb +22 -0
  166. data/processor/command/show_subcmd/basename.rb +20 -0
  167. data/processor/command/show_subcmd/confirm.rb +18 -0
  168. data/processor/command/show_subcmd/debug.rb +26 -0
  169. data/processor/command/show_subcmd/debug_subcmd/.gitignore +3 -0
  170. data/processor/command/show_subcmd/debug_subcmd/dbgr.rb +21 -0
  171. data/processor/command/show_subcmd/debug_subcmd/skip.rb +22 -0
  172. data/processor/command/show_subcmd/debug_subcmd/step.rb +22 -0
  173. data/processor/command/show_subcmd/different.rb +26 -0
  174. data/processor/command/show_subcmd/directories.rb +22 -0
  175. data/processor/command/show_subcmd/hidelevel.rb +41 -0
  176. data/processor/command/show_subcmd/highlight.rb +25 -0
  177. data/processor/command/show_subcmd/kernelstep.rb +34 -0
  178. data/processor/command/show_subcmd/max.rb +27 -0
  179. data/processor/command/show_subcmd/max_subcmd/.gitignore +2 -0
  180. data/processor/command/show_subcmd/max_subcmd/list.rb +38 -0
  181. data/processor/command/show_subcmd/max_subcmd/stack.rb +36 -0
  182. data/processor/command/show_subcmd/max_subcmd/string.rb +42 -0
  183. data/processor/command/show_subcmd/max_subcmd/width.rb +37 -0
  184. data/processor/command/show_subcmd/reload.rb +18 -0
  185. data/processor/command/show_subcmd/timer.rb +18 -0
  186. data/processor/command/show_subcmd/trace.rb +27 -0
  187. data/processor/command/show_subcmd/trace_subcmd/.gitignore +2 -0
  188. data/processor/command/show_subcmd/trace_subcmd/buffer.rb +64 -0
  189. data/processor/command/show_subcmd/trace_subcmd/print.rb +23 -0
  190. data/processor/command/show_subcmd/version.rb +23 -0
  191. data/processor/command/source.rb +133 -0
  192. data/processor/command/step.rb +97 -0
  193. data/processor/command/tbreak.rb +20 -0
  194. data/processor/command/unalias.rb +49 -0
  195. data/processor/command/undisplay.rb +63 -0
  196. data/processor/command/up.rb +89 -0
  197. data/processor/command.rb +173 -0
  198. data/processor/default.rb +64 -0
  199. data/processor/disassemble.rb +59 -0
  200. data/processor/display.rb +53 -0
  201. data/processor/eval.rb +97 -0
  202. data/processor/eventbuf.rb +101 -0
  203. data/processor/frame.rb +265 -0
  204. data/processor/help.rb +94 -0
  205. data/processor/hook.rb +134 -0
  206. data/processor/list.rb +123 -0
  207. data/processor/load_cmds.rb +253 -0
  208. data/processor/location.rb +228 -0
  209. data/processor/mock.rb +138 -0
  210. data/processor/msg.rb +74 -0
  211. data/processor/running.rb +244 -0
  212. data/processor/stepping.rb +135 -0
  213. data/processor/subcmd.rb +136 -0
  214. data/processor/validate.rb +379 -0
  215. data/processor/virtual.rb +33 -0
  216. data/processor.rb +404 -0
  217. data/rbx-trepanning.gemspec +39 -0
  218. data/sample/.gitignore +2 -0
  219. data/sample/list-terminal-colors.rb +139 -0
  220. data/sample/rocky-dot-trepanxrc +14 -0
  221. data/sample/rocky-trepanx-colors.rb +46 -0
  222. data/test/data/.gitignore +1 -0
  223. data/test/data/enable.right +36 -0
  224. data/test/data/fname-with-blank.cmd +6 -0
  225. data/test/data/fname-with-blank.right +6 -0
  226. data/test/data/inline-call.cmd +6 -0
  227. data/test/data/inline-call.right +14 -0
  228. data/test/data/quit-Xdebug.right +3 -0
  229. data/test/data/quit.cmd +5 -0
  230. data/test/data/quit.right +3 -0
  231. data/test/data/quit2.cmd +6 -0
  232. data/test/data/quit2.right +3 -0
  233. data/test/example/.gitignore +2 -0
  234. data/test/example/debugger-stop.rb +16 -0
  235. data/test/example/factorial.rb +10 -0
  236. data/test/example/fname with blank.rb +1 -0
  237. data/test/example/gcd-server.rb +22 -0
  238. data/test/example/gcd.rb +19 -0
  239. data/test/example/goto2goto.rb +11 -0
  240. data/test/example/inline-call.rb +23 -0
  241. data/test/example/null.rb +1 -0
  242. data/test/example/thread1.rb +3 -0
  243. data/test/functional/.gitignore +3 -0
  244. data/test/functional/fn_helper.rb +112 -0
  245. data/test/functional/test-break-name.rb +52 -0
  246. data/test/functional/test-break.rb +85 -0
  247. data/test/functional/test-eval.rb +115 -0
  248. data/test/functional/test-finish.rb +70 -0
  249. data/test/functional/test-fn_helper.rb +43 -0
  250. data/test/functional/test-list.rb +56 -0
  251. data/test/functional/test-next-bug.rb +49 -0
  252. data/test/functional/test-next.rb +101 -0
  253. data/test/functional/test-recursive-bt.rb +94 -0
  254. data/test/functional/test-step.rb +272 -0
  255. data/test/functional/test-step2.rb +35 -0
  256. data/test/functional/test-tbreak.rb +41 -0
  257. data/test/integration/.gitignore +3 -0
  258. data/test/integration/file-diff.rb +89 -0
  259. data/test/integration/helper.rb +81 -0
  260. data/test/integration/test-fname-with-blank.rb +16 -0
  261. data/test/integration/test-inline-call.rb +20 -0
  262. data/test/integration/test-quit.rb +47 -0
  263. data/test/unit/.gitignore +3 -0
  264. data/test/unit/cmd-helper.rb +50 -0
  265. data/test/unit/mock-helper.rb +10 -0
  266. data/test/unit/test-app-brkpt.rb +31 -0
  267. data/test/unit/test-app-brkptmgr.rb +51 -0
  268. data/test/unit/test-app-cmd_parse.rb +97 -0
  269. data/test/unit/test-app-cmd_parser.rb +23 -0
  270. data/test/unit/test-app-complete.rb +39 -0
  271. data/test/unit/test-app-condition.rb +18 -0
  272. data/test/unit/test-app-display.rb +22 -0
  273. data/test/unit/test-app-iseq.rb +64 -0
  274. data/test/unit/test-app-method.rb +54 -0
  275. data/test/unit/test-app-options.rb +94 -0
  276. data/test/unit/test-app-run.rb +14 -0
  277. data/test/unit/test-app-util.rb +44 -0
  278. data/test/unit/test-app-validate.rb +18 -0
  279. data/test/unit/test-base-cmd.rb +45 -0
  280. data/test/unit/test-base-subcmd.rb +57 -0
  281. data/test/unit/test-base-submgr.rb +24 -0
  282. data/test/unit/test-base-subsubcmd.rb +17 -0
  283. data/test/unit/test-bin-trepanx.rb +48 -0
  284. data/test/unit/test-cmd-alias.rb +48 -0
  285. data/test/unit/test-cmd-break.rb +66 -0
  286. data/test/unit/test-cmd-edit.rb +34 -0
  287. data/test/unit/test-cmd-exit.rb +27 -0
  288. data/test/unit/test-cmd-finish.rb +31 -0
  289. data/test/unit/test-cmd-help.rb +104 -0
  290. data/test/unit/test-cmd-kill.rb +54 -0
  291. data/test/unit/test-cmd-parse_list_cmd.rb +36 -0
  292. data/test/unit/test-cmd-source.rb +34 -0
  293. data/test/unit/test-cmd-step.rb +29 -0
  294. data/test/unit/test-command.rb +45 -0
  295. data/test/unit/test-completion.rb +48 -0
  296. data/test/unit/test-intf-user.rb +46 -0
  297. data/test/unit/test-io-input.rb +27 -0
  298. data/test/unit/test-io-tcp.rb +33 -0
  299. data/test/unit/test-io-tcpclient.rb +54 -0
  300. data/test/unit/test-io-tcpfns.rb +17 -0
  301. data/test/unit/test-io-tcpserver.rb +50 -0
  302. data/test/unit/test-proc-eval.rb +35 -0
  303. data/test/unit/test-proc-frame.rb +81 -0
  304. data/test/unit/test-proc-help.rb +16 -0
  305. data/test/unit/test-proc-hook.rb +30 -0
  306. data/test/unit/test-proc-list.rb +55 -0
  307. data/test/unit/test-proc-load_cmds.rb +51 -0
  308. data/test/unit/test-proc-location.rb +67 -0
  309. data/test/unit/test-proc-main.rb +95 -0
  310. data/test/unit/test-proc-validate.rb +139 -0
  311. data/test/unit/test-subcmd-help.rb +43 -0
  312. metadata +545 -0
@@ -0,0 +1,180 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative '../command'
5
+ require_relative '../../app/method'
6
+ require_relative '../../app/iseq'
7
+
8
+ class Trepan::Command::DisassembleCommand < Trepan::Command
9
+
10
+ include Trepanning::Method
11
+
12
+ NAME = File.basename(__FILE__, '.rb')
13
+ ALIASES = %w(disasm) # Note we have disable
14
+ CATEGORY = 'data'
15
+ HELP = <<-HELP
16
+ #{NAME} [--all | -a]
17
+ #{NAME} [method|LINE-NUM]...
18
+
19
+ Disassembles Rubinius VM instructions. By default, the bytecode for the
20
+ current line is disassembled only.
21
+
22
+ If a method name is given, disassemble just that method.
23
+
24
+ If a line number given, then disassemble just that line number if it
25
+ has bytecode assocated with that line. Note that if a line has
26
+ discontinuous regions we will show just the first region associated
27
+ with that line.
28
+
29
+ If the argument is '--all', the entire method is shown as bytecode.
30
+
31
+ Examples:
32
+ #{NAME} # dissasemble VM for current line
33
+ #{NAME} --all # disassemble entire current method
34
+ #{NAME} [1,2].max # disassemble max method of Array
35
+ #{NAME} Object.is_a? # disassemble Object.is_a?
36
+ #{NAME} is_a? # same as above (probably)
37
+ #{NAME} 6 # Disassemble line 6 if there is bytecode for it
38
+ #{NAME} 6 is_a? # The above two commands combined into one
39
+ HELP
40
+
41
+ NEED_STACK = true
42
+ SHORT_HELP = 'Show the bytecode for the current method'
43
+ DEFAULT_OPTIONS = {
44
+ :all => false,
45
+ }
46
+
47
+ completion %w(-a --all)
48
+
49
+ def disassemble_method(cm)
50
+ frame_ip = (@proc.frame.method == cm) ? @proc.frame.next_ip : nil
51
+ lines = cm.lines
52
+ next_line_ip = 0
53
+ next_i = 1
54
+ prefixes = []
55
+ disasm = ''
56
+ cm.decode.each do |insn|
57
+ show_line =
58
+ if insn.ip >= next_line_ip
59
+ next_line_ip = lines.at(next_i+1)
60
+ line_no = lines.at(next_i)
61
+ next_i += 2
62
+ true
63
+ else
64
+ false
65
+ end
66
+
67
+ prefixes << Trepan::ISeq::disasm_prefix(insn.ip, frame_ip, cm)
68
+ str = insn.to_s
69
+ if show_line
70
+ str +=
71
+ if insn.instance_variable_get('@comment')
72
+ ' '
73
+ elsif str[-1..-1] !~/\s/
74
+ ' '
75
+ else
76
+ ''
77
+ end
78
+ str += "# line: #{line_no}"
79
+ end
80
+ disasm += "#{str}\n"
81
+ end
82
+
83
+ # FIXME DRY with ../disassemble.rb
84
+ if settings[:highlight]
85
+ begin
86
+ require_relative '../../app/rbx-llvm'
87
+ @llvm_highlighter ||= CodeRay::Duo[:llvm, :term]
88
+ # llvm_scanner = CodeRay.scanner :llvm
89
+ # p llvm_scanner.tokenize(disasm)
90
+ disasm = @llvm_highlighter.encode(disasm)
91
+ rescue LoadError
92
+ errmsg 'Highlighting requested but CodeRay is not installed.'
93
+ end
94
+ end
95
+
96
+ disasm.split("\n").each_with_index do |inst, i|
97
+ msg ("#{prefixes[i]} #{inst}", :unlimited => true)
98
+ end
99
+ end
100
+
101
+ def parse_options(options, args) # :nodoc
102
+ parser = OptionParser.new do |opts|
103
+ opts.on('-a', '--all',
104
+ 'show entire method') do
105
+ options[:all] = true
106
+ end
107
+ end
108
+ begin
109
+ parser.parse! args
110
+ rescue OptionParser::InvalidOption => e
111
+ errmsg e
112
+ end
113
+ return options
114
+
115
+ end
116
+
117
+ # Run command.
118
+ def run(args)
119
+ my_args = args[1..-1]
120
+ options = parse_options(DEFAULT_OPTIONS.dup, my_args)
121
+ if my_args.empty?
122
+ if options[:all]
123
+ section "Bytecode for #{@proc.frame.vm_location.describe}"
124
+ disassemble_method(current_method)
125
+ else
126
+ @proc.show_bytecode
127
+ end
128
+ else
129
+ args[1..-1].each do |arg|
130
+ cm = @proc.parse_method(arg)
131
+ if cm
132
+ section "Bytecode for method #{arg}"
133
+ disassemble_method(cm.executable)
134
+ else
135
+ opts = {:msg_on_error => false }
136
+ line_num = @proc.get_an_int(arg, opts)
137
+ if line_num
138
+ cm = find_method_with_line(current_method, line_num)
139
+ if cm
140
+ @proc.show_bytecode(line_num)
141
+ else
142
+ errmsg "Can't find that bytecode for line #{line_num}"
143
+ end
144
+ else
145
+ errmsg "Method #{arg} not found"
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
152
+
153
+ if __FILE__ == $0
154
+ # Demo it.
155
+ require_relative '../mock'
156
+ dbgr, cmd = MockDebugger::setup
157
+ def five; 5 end
158
+ def foo(cmd)
159
+ puts "#{cmd.name}"
160
+ cmd.run([cmd.name])
161
+ puts '=' * 40
162
+ puts "#{cmd.name} --all"
163
+ # require_relative '../../lib/trepanning'; debugger
164
+ cmd.run([cmd.name, '--all'])
165
+ puts '=' * 40
166
+ cmd.run([cmd.name, '-a'])
167
+ puts '=' * 40
168
+ cmd.run([cmd.name, 'five'])
169
+ ## FIXME: someday handle:
170
+ # puts '=' * 40
171
+ # cmd.run([cmd.name, '-a', 'five'])
172
+ puts '=' * 40
173
+ cmd.run([cmd.name, 'MockDebugger::setup'])
174
+ puts '=' * 40
175
+ cmd.run([cmd.name, __LINE__.to_s])
176
+ require 'irb'
177
+ cmd.run([cmd.name, 'IRB.start'])
178
+ end
179
+ foo(cmd)
180
+ end
@@ -0,0 +1,84 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative '../command'
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
+
27
+ See also "undisplay", "enable", and "disable".
28
+ HELP
29
+
30
+ CATEGORY = 'data'
31
+ NEED_STACK = false
32
+ SHORT_HELP = 'Display expressions when entering debugger'
33
+ end
34
+
35
+ def run(args)
36
+
37
+ if args.size == 1
38
+ # Display anything active
39
+ @proc.run_eval_display
40
+ else
41
+ if %w(/c /x /o /f /s).member?(args[1])
42
+ if 2 == args.size
43
+ errmsg("Expecting an expression after the format")
44
+ return
45
+ end
46
+ format = args[1]
47
+ expr = args[2..-1].join(' ')
48
+ else
49
+ format = nil
50
+ expr = args[1..-1].join(' ')
51
+ end
52
+
53
+ dp = @proc.displays.add(@proc.frame, expr, format)
54
+ unless dp
55
+ errmsg('Error evaluating "%s" in the current frame' % expr)
56
+ return
57
+ end
58
+ msg(dp.to_s(@proc.frame))
59
+ @proc.cmdloop_prehooks.insert_if_new(5, *@proc.display_hook)
60
+ end
61
+ end
62
+ end
63
+
64
+ if __FILE__ == $0
65
+ # Demo it.
66
+ require_relative '../mock'
67
+ dbgr, cmd = MockDebugger::setup
68
+
69
+ def run_cmd(cmd, args)
70
+ cmd.run(args)
71
+ puts '==' * 10
72
+ end
73
+
74
+ # run_cmd(cmd, [cmd.name])
75
+ # run_cmd(cmd, [cmd.name, '/x', '10'])
76
+ # run_cmd(cmd, [cmd.name, 'd'])
77
+ # run_cmd(cmd, [cmd.name])
78
+ e = 5
79
+ vm_locations = Rubinius::VM.backtrace(0, true)
80
+ cmd.proc.instance_variable_set('@frame ',
81
+ Trepan::Frame.new(self, 0, vm_locations[0]))
82
+
83
+ run_cmd(cmd, [cmd.name, 'e'])
84
+ end
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010, 2011 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
+ Trepan::Util.suppress_warnings {
11
+ old_verbose = $VERBOSE
12
+ $VERBOSE = nil
13
+ HELP = <<-HELP
14
+ #{NAME} [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
+ HELP
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
+ }
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,74 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative '../command'
5
+
6
+ class Trepan::Command::EditCommand < Trepan::Command
7
+
8
+ old_verbose = $VERBOSE
9
+ $VERBOSE = nil
10
+ NAME = File.basename(__FILE__, '.rb')
11
+ HELP = <<-HELP
12
+ #{NAME} [[FILE] [LINE]]
13
+
14
+ With no argument, edits file containing most recent line listed.
15
+ The value of the environment variable EDITOR is used for the
16
+ editor to run. If no EDITOR environment variable is set /bin/ex
17
+ is used. The editor should support line and file positioning via
18
+ editor-name +line file-name
19
+ (Most editors do.)
20
+
21
+ Examples:
22
+ #{NAME} # Edit current location
23
+ #{NAME} 7 # Edit current file at line 7
24
+ #{NAME} test.rb # Edit test.rb, line 1
25
+ #{NAME} test.rb 10 # Edit test.rb line 10
26
+ HELP
27
+
28
+ ALIASES = %w(e)
29
+ CATEGORY = 'files'
30
+ NEED_STACK = false
31
+ SHORT_HELP = 'Invoke an editor on some source code'
32
+ MAX_ARGS = 2
33
+ $VERBOSE = old_verbose
34
+
35
+ # FIXME: redo with locations and kparse.
36
+ def run(args)
37
+ case args.size
38
+ when 1
39
+ file = @proc.frame.file
40
+ line = @proc.frame.line
41
+ when 2
42
+ line = Integer(args[1]) rescue nil
43
+ if line
44
+ file = @proc.frame.file
45
+ else
46
+ file = args[1]
47
+ line = 1
48
+ end
49
+ when 3
50
+ line, file = args[2], args[1]
51
+ else
52
+ errmsg "edit needs at most 2 args."
53
+ end
54
+ editor = ENV['EDITOR'] || '/bin/ex'
55
+ if File.readable?(file)
56
+ file = File.basename(file) if settings[:basename]
57
+ edit_cmd = "#{editor} +#{line} \"#{file}\""
58
+ msg "Running #{edit_cmd}..."
59
+ system(edit_cmd)
60
+ msg "Warning: return code was #{$?.exitstatus}" if $?.exitstatus != 0
61
+ else
62
+ errmsg "File \"#{file}\" is not readable."
63
+ end
64
+ end
65
+ end
66
+
67
+ if __FILE__ == $0
68
+ require_relative '../mock'
69
+ dbgr, cmd = MockDebugger::setup
70
+ ENV['EDITOR'] = 'echo FAKE-EDITOR'
71
+ cmd.run [cmd.name]
72
+ cmd.run [cmd.name, '7']
73
+ cmd.run [cmd.name, __FILE__, '10']
74
+ end
@@ -0,0 +1,43 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative 'disable'
5
+
6
+ # enable breakpoint command. Is like disable but the parameter
7
+ # to @proc.en_disable_breakpoint_by_number is different (set as
8
+ # ENABLE_PARM below).
9
+ class Trepan::Command::EnableCommand < Trepan::Command::DisableCommand
10
+
11
+ Trepan::Util.suppress_warnings {
12
+ NAME = File.basename(__FILE__, '.rb')
13
+ HELP = <<-HELP
14
+ #{NAME} [display] NUM1 [NUM2 ...]
15
+
16
+ Enables breakpoints or display NUM1. Breakpoints numbers are given as
17
+ a space-separated list numbers.
18
+
19
+ See also "disable" and "info break".
20
+ HELP
21
+
22
+ ALIASES = %w(en)
23
+ SHORT_HELP = 'Enable some breakpoints'
24
+ }
25
+
26
+ def initialize(proc)
27
+ super
28
+ @enable_parm = true # true if enable
29
+ end
30
+
31
+ end
32
+
33
+ if __FILE__ == $0
34
+ require_relative '../mock'
35
+ dbgr, cmd = MockDebugger::setup
36
+ cmd.run([cmd.name])
37
+ cmd.run([cmd.name, '1'])
38
+ cmdproc = cmd.proc
39
+ cmds = cmdproc.commands
40
+ break_cmd = cmds['break']
41
+ break_cmd.run(['break', cmdproc.frame.source_location[0].to_s])
42
+ cmd.run([cmd.name, '1'])
43
+ end
@@ -0,0 +1,93 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative '../command'
5
+ require_relative '../../app/util'
6
+
7
+ class Trepan::Command::EvalCommand < Trepan::Command
8
+
9
+ old_verbose = $VERBOSE
10
+ $VERBOSE = nil
11
+ NAME = File.basename(__FILE__, '.rb')
12
+ HELP = <<-HELP
13
+ #{NAME} [STRING]
14
+
15
+ Run code in the context of the current frame.
16
+
17
+ The value of the expression is stored into a global variable so it
18
+ may be used again easily. The name of the global variable is printed
19
+ next to the inspect output of the value.
20
+
21
+ If no string is given, we run the string from the current source code
22
+ about to be run. If the command ends ? (via an alias) and no string is
23
+ given we will the following translations occur:
24
+
25
+ {if|elsif|unless} expr [then] => expr
26
+ {until|while} expr [do] => expr
27
+ return expr => expr
28
+ case expr => expr
29
+ def fn(params) => [params]
30
+ var = expr => expr
31
+
32
+ The above is done via regular expression. No fancy parsing is done, say,
33
+ to look to see if expr is split across a line or whether var an assigment
34
+ might have multiple variables on the left-hand side.
35
+
36
+ Examples:
37
+
38
+ #{NAME} 1+2 # 3
39
+ #{NAME} @v
40
+ #{NAME} # Run current source-code line
41
+ #{NAME}? # but strips off leading 'if', 'while', ..
42
+ # from command
43
+
44
+ See also 'set autoeval'. The command helps one predict future execution.
45
+ See 'set buffer trace' for showing what may have already been run.
46
+ HELP
47
+
48
+ ALIASES = %w(eval? ev? ev)
49
+ CATEGORY = 'data'
50
+ NEED_STACK = true
51
+ SHORT_HELP = 'Run code in the current context'
52
+ $VERBOSE = old_verbose
53
+
54
+ def complete(prefix)
55
+ if prefix.empty?
56
+ if @proc.leading_str.start_with?('eval?')
57
+ Trepan::Util.extract_expression @proc.current_source_text
58
+ else
59
+ @proc.current_source_text
60
+ end
61
+ else
62
+ prefix
63
+ end
64
+ end
65
+
66
+ def run(args)
67
+ if args.size == 1
68
+ text = @proc.current_source_text
69
+ ## FIXME turn into a subroutine and use in complete.
70
+ if '?' == args[0][-1..-1]
71
+ text = Trepan::Util::extract_expression(text)
72
+ msg "eval: #{text}"
73
+ end
74
+ else
75
+ text = @proc.cmd_argstr
76
+ end
77
+ @proc.eval_code(text, settings[:maxstring])
78
+ end
79
+ end
80
+
81
+ if __FILE__ == $0
82
+ require_relative '../mock'
83
+ dbgr, cmd = MockDebugger::setup
84
+ arg_str = '1 + 2'
85
+ cmd.proc.instance_variable_set('@cmd_argstr', arg_str)
86
+ puts "eval #{arg_str} is: #{cmd.run([cmd.name, arg_str])}"
87
+ arg_str = 'return "foo"'
88
+ # def cmd.proc.current_source_text
89
+ # 'return "foo"'
90
+ # end
91
+ # cmd.proc.instance_variable_set('@cmd_argstr', arg_str)
92
+ # puts "eval? #{arg_str} is: #{cmd.run([cmd.name + '?'])}"
93
+ end
@@ -0,0 +1,83 @@
1
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require 'rubygems'; require 'require_relative'
3
+ require_relative '../command'
4
+ class Trepan::Command::ExitCommand < Trepan::Command
5
+
6
+ unless defined?(HELP)
7
+ NAME = File.basename(__FILE__, '.rb')
8
+ ALIASES = %w(quit q q! quit! exit!)
9
+ HELP = <<-HELP
10
+ #{NAME} [exitcode] [unconditionally] - hard exit of the debugged program.
11
+
12
+ The program being debugged is exited via exit!() which does not run
13
+ the Kernel at_exit finalizers. If a return code is given, that is the
14
+ return code passed to exit() - presumably the return code that will be
15
+ passed back to the OS. If no exit code is given, 0 is used.
16
+
17
+ If you are in interactive mode, and confirm is not set off, you are
18
+ prompted to confirm quitting. However if you do not want to be
19
+ prompted, add ! the end. (vim/vi/ed users can use alias q!).
20
+
21
+ Examples:
22
+ #{NAME} # quit prompting if we are interactive
23
+ #{NAME} unconditionally # quit without prompting
24
+ #{NAME}! # same as above
25
+ #{NAME} 0 # same as "quit"
26
+ #{NAME}! 1 # unconditional quit setting exit code 1
27
+
28
+ See also "kill" and "set confirm".'
29
+ HELP
30
+
31
+ CATEGORY = 'support'
32
+ MAX_ARGS = 2 # Need at most this many
33
+ SHORT_HELP = 'Exit program via "exit!()"'
34
+ end
35
+
36
+ # FIXME: Combine 'quit' and 'exit'. The only difference is
37
+ # whether exit! or exit is used.
38
+
39
+ # This method runs the command
40
+ def run(args) # :nodoc
41
+ unconditional =
42
+ if args.size > 1 && args[-1] == 'unconditionally'
43
+ args.shift
44
+ true
45
+ elsif args[0][-1..-1] == '!'
46
+ true
47
+ else
48
+ false
49
+ end
50
+ unless unconditional || confirm('Really quit?', false)
51
+ msg('Quit not confirmed.')
52
+ return
53
+ end
54
+
55
+ if (args.size > 1)
56
+ if args[1] =~ /\d+/
57
+ exitrc = args[1].to_i;
58
+ else
59
+ errmsg "Bad an Integer return type \"#{args[1]}\"";
60
+ return;
61
+ end
62
+ else
63
+ exitrc = 0
64
+ end
65
+
66
+ # FIXME: Is this the best/most general way?
67
+ @proc.finalize
68
+ @proc.dbgr.intf[-1].finalize
69
+
70
+ # No graceful way to stop threads...
71
+ # A little harsh, but for now let's go with this.
72
+ exit! exitrc
73
+ end
74
+ end
75
+
76
+ if __FILE__ == $0
77
+ require_relative '../mock'
78
+ dbgr, cmd = MockDebugger::setup
79
+ Process.fork { cmd.run([cmd.name]) } if
80
+ Process.respond_to?(:fork)
81
+ cmd.run([cmd.name, 'foo'])
82
+ cmd.run([cmd.name, '10'])
83
+ end
@@ -0,0 +1,80 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative '../command'
5
+
6
+ class Trepan::Command::FinishCommand < Trepan::Command
7
+
8
+ unless defined?(HELP)
9
+ ALIASES = %w(fin finish+ fin+)
10
+ CATEGORY = 'running'
11
+ NAME = File.basename(__FILE__, '.rb')
12
+ HELP = <<-HELP
13
+ #{NAME}
14
+ #{NAME}+
15
+
16
+ Continue execution until leaving the current method. Sometimes this
17
+ is called 'step out'.
18
+
19
+ Normally, stopping occurs just before the return on or yield out of a
20
+ method. However sometimes one wants go to the calling method or place
21
+ just beyond the current method.For this, suffix the command or an
22
+ alias of it with a plus sign. The disadvantange of this is that you
23
+ will no longer be in the scope of the method and so you won't be able
24
+ to see variables of that method.
25
+
26
+ Examples:
27
+ #{NAME}
28
+ #{NAME}+
29
+
30
+ See also commands:
31
+ 'continue', 'break', 'next', 'nexti', 'step' for other ways to continue.
32
+ HELP
33
+ NEED_RUNNING = true
34
+ MAX_ARGS = 1 # Need at most this many.
35
+ NEED_STACK = true
36
+ SHORT_HELP = 'Step to end of current method (step out)'
37
+ end
38
+
39
+ # This method runs the command
40
+ def run(args) # :nodoc
41
+ opts = @proc.parse_next_step_suffix(args[0])
42
+ if args.size == 1
43
+ # Form is: "finish" which means "finish 1"
44
+ level_count = 0
45
+ else
46
+ count_str = args[1]
47
+ count_opts = {
48
+ :msg_on_error =>
49
+ "The '#{NAME}' command argument must eval to an integer. Got: %s" %
50
+ count_str,
51
+ :min_value => 1
52
+ }
53
+ count = @proc.get_an_int(count_str, count_opts)
54
+ return unless count
55
+ # step 1 is core.level_count = 0 or "stop next event"
56
+ level_count = count - 1
57
+ end
58
+ if 0 == level_count and %w(return c-return).member?(@proc.event)
59
+ errmsg "You are already at the requested return event."
60
+ else
61
+ @proc.finish(level_count, opts)
62
+ end
63
+ end
64
+ end
65
+
66
+ if __FILE__ == $0
67
+ require_relative '../mock'
68
+ dbgr, cmd = MockDebugger::setup
69
+ [%W(#{cmd.name}), %w(fin 2-1), %w(n foo)].each do |c|
70
+ cmd.proc.instance_variable_set('@return_to_program', false)
71
+ cmd.run(c)
72
+ puts 'return_to_program: %s' % cmd.proc.instance_variable_get('@return_to_program')
73
+ puts 'step_count: %s' % cmd.proc.instance_variable_get('@step_count')
74
+ end
75
+ [%w(fin), [cmd.name]].each do |c|
76
+ cmd.proc.leave_cmd_loop = false
77
+ result = cmd.run(c)
78
+ puts cmd.proc.different_pos
79
+ end
80
+ end