rbx-trepanning 0.2.0-universal-rubinius-2.0

Sign up to get free protection for your applications and to get access to all the features.
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
data/processor/mock.rb ADDED
@@ -0,0 +1,138 @@
1
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
+ # Mock setup for commands.
3
+ require 'rubygems'; require 'require_relative'
4
+
5
+ require_relative '../processor'
6
+
7
+ # require_relative '../app/core'
8
+ require_relative '../app/default'
9
+ require_relative '../app/frame'
10
+ require_relative '../interface/user' # user interface (includes I/O)
11
+
12
+ module MockDebugger
13
+ class MockDebugger
14
+ attr_accessor :trace_filter # Procs/Methods we ignore.
15
+
16
+ attr_accessor :frame # Actually a "Rubinius::Location object
17
+ attr_accessor :core # access to Debugger::Core instance
18
+ attr_accessor :intf # The way the outside world interfaces with us.
19
+ attr_reader :initial_dir # String. Current directory when program
20
+ # started. Used in restart program.
21
+ attr_accessor :restart_argv # How to restart us, empty or nil.
22
+ # Note restart[0] is typically $0.
23
+ attr_reader :settings # Hash[:symbol] of things you can configure
24
+ attr_accessor :processor
25
+
26
+ # FIXME: move more stuff of here and into Trepan::CmdProcessor
27
+ # These below should go into Trepan::CmdProcessor.
28
+ attr_reader :cmd_argstr, :cmd_name, :vm_locations, :current_frame,
29
+ :debugee_thread, :completion_proc
30
+
31
+ def initialize(settings={:start_frame=>1})
32
+ @before_cmdloop_hooks = []
33
+ @settings = Trepan::DEFAULT_SETTINGS.merge(settings)
34
+ @intf = [Trepan::UserInterface.new(nil, nil,
35
+ :history_save=>false)]
36
+ @vm_locations = Rubinius::VM.backtrace(settings[:start_frame], true)
37
+ @current_frame = Trepan::Frame.new(self, 0, @vm_locations[0])
38
+ @debugee_thread = Thread.current
39
+ @frames = []
40
+ @restart_argv = Rubinius::OS_STARTUP_DIR
41
+
42
+ ## @core = Trepan::Core.new(self)
43
+ @trace_filter = []
44
+
45
+ @completion_proc = Proc.new{|str| str}
46
+
47
+ # Don't allow user commands in mocks.
48
+ ## @core.processor.settings[:user_cmd_dir] = nil
49
+
50
+ end
51
+
52
+ def frame(num)
53
+ @frames[num] ||= Trepan::Frame.new(self, num, @vm_locations[num])
54
+ end
55
+ end
56
+
57
+ # Common Mock debugger setup
58
+ def setup(name=nil, show_constants=true)
59
+ unless name
60
+ loc = Rubinius::VM.backtrace(1, true)[0]
61
+ name = File.basename(loc.file, '.rb')
62
+ end
63
+
64
+ if ARGV.size > 0 && ARGV[0] == 'debug'
65
+ require_relative '../lib/trepanning'
66
+ dbgr = Trepan.new
67
+ dbgr.debugger
68
+ else
69
+ dbgr = MockDebugger.new(:start_frame=>2)
70
+ end
71
+
72
+ cmdproc = Trepan::CmdProcessor.new(dbgr)
73
+ cmdproc.frame = dbgr.frame(0)
74
+ dbgr.processor = cmdproc
75
+
76
+ cmdproc.load_cmds_initialize
77
+ cmds = cmdproc.commands
78
+ cmd = cmds[name]
79
+ cmd.proc.frame_setup
80
+ cmd.proc.event = 'debugger-call'
81
+ show_special_class_constants(cmd) if show_constants
82
+
83
+ def cmd.confirm(prompt, default)
84
+ true
85
+ end
86
+ def cmd.msg_nocr(message, opts={})
87
+ print message
88
+ end
89
+ def cmd.section(message, opts={})
90
+ puts "Section: #{message}"
91
+ end
92
+
93
+ return dbgr, cmd
94
+ end
95
+ module_function :setup
96
+
97
+ def sub_setup(sub_class, run=true)
98
+ sub_name = sub_class.const_get('PREFIX')
99
+ dbgr, cmd = setup(sub_name[0], false)
100
+ sub_cmd = sub_class.new(cmd)
101
+ sub_cmd.summary_help(sub_cmd.name)
102
+ puts
103
+ sub_cmd.run([cmd.name]) if run
104
+ return sub_cmd
105
+ end
106
+ module_function :sub_setup
107
+
108
+ def subsub_setup(sub_class, subsub_class, run=true)
109
+ subsub_name = subsub_class.const_get('PREFIX')
110
+ dbgr, cmd = setup(subsub_name[0], false)
111
+ sub_cmd = sub_class.new(dbgr.processor, cmd)
112
+ subsub_cmd = subsub_class.new(cmd.proc, sub_cmd, subsub_name.join(''))
113
+ subsub_cmd.run([subsub_cmd.name]) if run
114
+ return subsub_cmd
115
+ end
116
+ module_function :subsub_setup
117
+
118
+ def show_special_class_constants(cmd)
119
+ puts 'ALIASES: %s' % [cmd.class.const_get('ALIASES').inspect] if
120
+ cmd.class.constants.member?(:ALIASES)
121
+ %w(CATEGORY MIN_ARGS MAX_ARGS
122
+ NAME NEED_STACK SHORT_HELP).each do |name|
123
+ puts '%s: %s' % [name, cmd.class.const_get(name).inspect]
124
+ end
125
+ puts '-' * 30
126
+ puts cmd.class.const_get('HELP')
127
+ puts '=' * 30
128
+ end
129
+ module_function :show_special_class_constants
130
+
131
+ end
132
+
133
+ if __FILE__ == $0
134
+ dbgr = MockDebugger::MockDebugger.new
135
+ p dbgr.settings
136
+ puts '=' * 10
137
+ # p dbgr.core.processor.settings
138
+ end
data/processor/msg.rb ADDED
@@ -0,0 +1,74 @@
1
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
+ # I/O related command processor methods
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative '../app/util'
5
+ require_relative 'virtual'
6
+
7
+ begin require 'term/ansicolor'; rescue LoadError; end
8
+
9
+ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
10
+ attr_accessor :ruby_highlighter
11
+
12
+ def confirm(msg, default)
13
+ @settings[:confirm] ? @dbgr.intf[-1].confirm(msg, default) : true
14
+ end
15
+
16
+ def errmsg(message, opts={})
17
+ if message.kind_of?(Array)
18
+ message.each do |mess|
19
+ errmsg(mess, opts)
20
+ end
21
+ return
22
+ else
23
+ message = safe_rep(message) unless opts[:unlimited]
24
+ end
25
+ if @settings[:highlight] && defined?(Term::ANSIColor)
26
+ message =
27
+ Term::ANSIColor.italic + message + Term::ANSIColor.reset
28
+ end
29
+ @dbgr.intf[-1].errmsg(message)
30
+ end
31
+
32
+ def msg(message, opts={})
33
+ message = safe_rep(message) unless opts[:unlimited]
34
+ message = ruby_format(message) if opts[:code]
35
+ @dbgr.intf[-1].msg(message)
36
+ end
37
+
38
+ def msg_nocr(message, opts={})
39
+ message = safe_rep(message) unless opts[:unlimited]
40
+ @dbgr.intf[-1].msg_nocr(message)
41
+ end
42
+
43
+ def read_command()
44
+ @dbgr.intf[-1].read_command(@prompt)
45
+ end
46
+
47
+ def ruby_format(text)
48
+ return text unless settings[:highlight]
49
+ unless @ruby_highlighter
50
+ begin
51
+ require 'coderay'
52
+ require 'term/ansicolor'
53
+ @ruby_highlighter = CodeRay::Duo[:ruby, :term]
54
+ rescue LoadError
55
+ return text
56
+ end
57
+ end
58
+ return @ruby_highlighter.encode(text)
59
+ end
60
+
61
+ def safe_rep(str)
62
+ Trepan::Util::safe_repr(str, @settings[:maxstring])
63
+ end
64
+
65
+ def section(message, opts={})
66
+ message = safe_rep(message) unless opts[:unlimited]
67
+ if @settings[:highlight] && defined?(Term::ANSIColor)
68
+ message =
69
+ Term::ANSIColor.bold + message + Term::ANSIColor.reset
70
+ end
71
+ @dbgr.intf[-1].msg(message)
72
+ end
73
+
74
+ end
@@ -0,0 +1,244 @@
1
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require 'set'
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative 'virtual'
5
+ class Trepan
6
+ class CmdProcessor < VirtualCmdProcessor
7
+
8
+ attr_accessor :ignore_file_re # Hash[file_re] -> String
9
+ # action. File re's we don't want
10
+ # to stop while stepping. Like
11
+ # ignore_methods. Skipping kernel methods
12
+ # is handled this way.
13
+ attr_accessor :ignore_methods # Hash[CompiledMethod] -> String:
14
+ # action. Methods we don't want to
15
+ # ever stop while stepping. action
16
+ # is 'step' or 'next'.
17
+ attr_accessor :stop_condition # String or nil. When not nil
18
+ # this has to eval non-nil
19
+ # in order to stop.
20
+ attr_accessor :stop_events # Set or nil. If not nil, only
21
+ # events in this set will be
22
+ # considered for stopping. This is
23
+ # like core.step_events (which
24
+ # could be used instead), but it is
25
+ # a set of event names rather than
26
+ # a bitmask and it is intended to
27
+ # be more temporarily changed via
28
+ # "step>" or "step!" commands.
29
+ attr_accessor :step_count
30
+ attr_accessor :to_method
31
+
32
+ # # Does whatever needs to be done to set to continue program
33
+ # # execution.
34
+ # # FIXME: turn line_number into a condition.
35
+
36
+ def continue(return_to_program)
37
+ @next_level = 32000 # I'm guessing the stack size can't
38
+ # ever reach this
39
+ @next_thread = nil
40
+ @step_count = -1 # No more event stepping
41
+ if 'step-finish' == return_to_program
42
+ step_to_return_or_yield
43
+ return_to_program = 'step'
44
+ end
45
+ @return_to_program = return_to_program
46
+ end
47
+
48
+ # Does whatever setup needs to be done to set to ignore stepping
49
+ # to the finish of the current method. Elsewhere in
50
+ # "stepping_skip?" we do the checking.
51
+ def finish(level_count=0, opts={})
52
+ step_to_return_or_yield
53
+ continue('finish')
54
+ @next_level = @stack_size - level_count
55
+ @next_thread = @current_thread
56
+
57
+ @step_count = 2 if 'nostack' == opts[:different_pos]
58
+
59
+ # # Try high-speed (run-time-assisted) method
60
+ # @frame.trace_off = true # No more tracing in this frame
61
+ # @frame.return_stop = true # don't need to
62
+ end
63
+
64
+ def step_finish
65
+ step_to_return_or_yield
66
+ continue('step')
67
+ @next_thread = @current_thread
68
+ end
69
+
70
+ # Does whatever needs to be done to set to "next" program
71
+ # execution.
72
+ def next(step_count=1, opts={})
73
+ step('step', step_count, opts)
74
+ @next_level = opts[:next_level] || @stack_size
75
+ @next_thread = Thread.current
76
+ end
77
+
78
+ # Does whatever needs to be done to set to step program
79
+ # execution.
80
+ def step(return_to_program, step_count=1, opts={}, condition=nil)
81
+ continue(return_to_program)
82
+ @step_count = step_count
83
+ @different_pos = opts[:different_pos] if
84
+ opts.keys.member?(:different_pos)
85
+ @stop_condition = condition
86
+ @stop_events = opts[:stop_events] if
87
+ opts.keys.member?(:stop_events)
88
+ @to_method = opts[:to_method]
89
+ end
90
+
91
+ def quit(cmd='exit')
92
+ @next_level = 32000 # I'm guessing the stack size can't
93
+ # ever reach this
94
+ @next_thread = nil
95
+ @step_count = -1 # No more event stepping
96
+ @leave_cmd_loop = true # Break out of the processor command loop.
97
+ @settings[:autoirb] = false
98
+ @cmdloop_prehooks.delete_by_name('autoirb')
99
+ @commands['exit'].run([cmd])
100
+ end
101
+
102
+ def parse_next_step_suffix(step_cmd)
103
+ opts = {}
104
+ case step_cmd[-1..-1]
105
+ when '-'
106
+ opts[:different_pos] = false
107
+ when '+'
108
+ opts[:different_pos] = 'nostack'
109
+ when '='
110
+ opts[:different_pos] = true
111
+ when '!'
112
+ opts[:stop_events] = Set.new(%w(raise))
113
+ when '<'
114
+ opts[:stop_events] = Set.new(%w(c-return return))
115
+ when '>'
116
+ opts[:stop_events] = Set.new(%w(c-call call))
117
+ if step_cmd.size > 1 && step_cmd[-2..-2] == '<'
118
+ opts[:stop_events] = Set.new(%w(c-call c-return call return))
119
+ else
120
+ opts[:stop_events] = Set.new(%w(c-call call))
121
+ end
122
+ end
123
+ return opts
124
+ end
125
+
126
+ def running_initialize
127
+ @ignore_file_re = {}
128
+ @ignore_methods = {}
129
+
130
+ @step_count = 0
131
+ @stop_condition = nil
132
+ @stop_events = nil
133
+ @to_method = nil
134
+ end
135
+
136
+ # If we are not in some kind of steppable event, return
137
+ # false. If we are in a steppable event, update step state
138
+ # and return true if the step count is 0 and other conditions
139
+ # like the @settings[:different] are met.
140
+ def stepping_skip?
141
+
142
+ if @settings[:'debugskip']
143
+ puts "diff: #{@different_pos}, event : #{@event}, #{@stop_events.inspect}"
144
+ puts "step_count : #{@step_count}"
145
+ puts "next_level : #{@next_level}, ssize : #{@stack_size}"
146
+ puts "next_thread : #{@next_thread}, thread: #{Thread.current}"
147
+ end
148
+
149
+ return true if
150
+ !frame || (@next_level < @stack_size &&
151
+ Thread.current == @next_thread && @event != 'raise')
152
+
153
+ if @step_count < 0
154
+ # We may eventually stop for some other reason, but it's not
155
+ # because we were stepping here.
156
+ msg "skip: step_count < 0 #{debug_loc}" if @settings[:debugskip]
157
+ return false
158
+ end
159
+
160
+ @ignore_file_re.each_pair do |file_re, action|
161
+ if frame.vm_location.method.active_path =~ file_re
162
+ @return_to_program = action
163
+ msg "skip re: #{debug_loc}" if @settings[:debugskip]
164
+ return true
165
+ end
166
+ end
167
+
168
+ ms = frame.method.scope
169
+ @ignore_methods.each do |m, val|
170
+ # Guard against crap put into @ignore_methods
171
+ unless m.respond_to?(:scope)
172
+ @ignore_methods.delete(m)
173
+ next
174
+ end
175
+ if ms == m.scope
176
+ msg "skip ignore method: #{debug_loc}" if @settings[:debugskip]
177
+ @return_to_program = val
178
+ return true
179
+ end
180
+ end
181
+
182
+ # Only skip on these kinds of events
183
+ unless %w(step-call line return).include?(@event)
184
+ msg "skip non-line: #{@event} #{debug_loc}" if @settings[:debugskip]
185
+ return false
186
+ end
187
+
188
+ # We are in some kind of stepping event, so do whatever we
189
+ # do to record that we've hit the step. Whether we decide
190
+ # to stop, will be done after recording the step took place.
191
+ @step_count -= 1 unless step_count == 0
192
+ new_pos = [@frame.file, @frame.line,
193
+ @stack_size, @current_thread, @event]
194
+
195
+
196
+ # Decide whether this step is skippable.
197
+ should_skip = false
198
+
199
+ if @settings[:debugskip]
200
+ msg("last: #{@last_pos.inspect}, ")
201
+ msg("new: #{new_pos.inspect}")
202
+ msg("skip: #{should_skip.inspect}, event: #{@event}")
203
+ msg("@step_count: #{@step_count}")
204
+ end
205
+
206
+ @last_pos[2] = new_pos[2] if 'nostack' == @different_pos
207
+ condition_met =
208
+ if @stop_condition
209
+ puts "stop_cond #{@stop_condition}" if @settings[:'debugskip']
210
+ debug_eval_no_errmsg(@stop_condition)
211
+ elsif @to_method
212
+ puts "method #{@frame.method} #{@to_method}" if
213
+ @settings[:'debugskip']
214
+ @frame.method == @to_method
215
+ else
216
+ puts 'uncond' if @settings[:'debugskip']
217
+ @step_count == 0
218
+ end
219
+
220
+ msg("condition_met: #{condition_met}, last: #{@last_pos}, " +
221
+ "new: #{new_pos}, different #{@different_pos.inspect}") if
222
+ @settings[:'debugskip']
223
+
224
+ should_skip = ((@last_pos[0..3] == new_pos[0..3] && @different_pos) ||
225
+ !condition_met)
226
+
227
+ msg("should_skip: #{should_skip}, #{debug_loc}") if @settings[:debugskip]
228
+
229
+ @last_pos = new_pos
230
+
231
+ unless should_skip
232
+ # Set up the default values for the
233
+ # next time we consider step skipping.
234
+ @different_pos = @settings[:different]
235
+ # @stop_events = nil
236
+ end
237
+
238
+ @return_to_program = 'step' if should_skip &&
239
+ (!@return_to_program || 'finish' == @return_to_program)
240
+ return should_skip
241
+ end
242
+
243
+ end
244
+ end
@@ -0,0 +1,135 @@
1
+ require 'rubygems'; require 'require_relative'
2
+ require_relative '../app/iseq'
3
+ require_relative 'virtual'
4
+ class Trepan
5
+ class CmdProcessor < VirtualCmdProcessor
6
+
7
+ def stepping_initialize
8
+ @step_brkpts = []
9
+ end
10
+
11
+ def stepping_breakpoint_finalize
12
+ @step_brkpts.each do |bp|
13
+ bp.remove!
14
+ end
15
+ end
16
+
17
+ def remove_step_brkpt
18
+ return unless @step_bp
19
+ @step_brkpts = @step_brkpts.select do |bp|
20
+ (bp != @step_bp) && bp.active?
21
+ end
22
+ @step_bp.remove!
23
+ end
24
+
25
+ # It might be interesting to allow stepping within a parent frame
26
+ def step_over_by(step, frame=@top_frame)
27
+
28
+ f = frame
29
+
30
+ meth = f.method
31
+ possible_line = f.line + step
32
+ next_ip = f.next_ip == f.ip ? f.next_ip + 1 : f.next_ip
33
+ # BUGGY: remove after writing a decent test case for this.
34
+ # See beginning of rbx-require/require_relative.
35
+ fin_ip = meth.first_ip_on_line_after(possible_line, f.next_ip)
36
+ # fin_ip = meth.first_ip_on_line_after(possible_line, next_ip)
37
+
38
+ unless fin_ip
39
+ return step_to_parent('line')
40
+ end
41
+
42
+ set_breakpoints_between(meth, f.next_ip, fin_ip)
43
+ end
44
+
45
+ def step_to_return_or_yield
46
+ f = @frame
47
+ unless f
48
+ msg 'Unable to find frame to finish'
49
+ return
50
+ end
51
+
52
+ meth = f.method
53
+ fin_ip = meth.lines.last
54
+
55
+ set_breakpoints_on_return_between(meth, f.next_ip, fin_ip)
56
+ end
57
+
58
+ def step_to_parent(event='return')
59
+ f = parent_frame
60
+ unless f
61
+ errmsg "Unable to find parent frame to step to next"
62
+ return nil
63
+ end
64
+ meth = f.method
65
+ ip = f.ip
66
+
67
+ bp = Breakpoint.for_ip(meth, ip, {:event => event, :temp => true})
68
+ bp.scoped!(parent_frame.scope)
69
+ bp.activate
70
+
71
+ return bp
72
+ end
73
+
74
+ # Sets temporary breakpoints in met between start_ip and fin_ip.
75
+ # We also set a temporary breakpoint in the caller.
76
+ def set_breakpoints_between(meth, start_ip, fin_ip)
77
+ opts = {:event => 'line', :temp => true}
78
+ ips = ISeq.goto_between(meth, start_ip, fin_ip)
79
+ bps = []
80
+
81
+ if ips.kind_of? Fixnum
82
+ if ips == -1
83
+ errmsg "No place to step to"
84
+ return nil
85
+ elsif ips == -2
86
+ bps << step_to_parent(event='line')
87
+ ips = []
88
+ else
89
+ ips = [ips]
90
+ end
91
+ end
92
+
93
+ msg "temp ips: #{ips.inspect}" if settings[:debugstep]
94
+ ips.each do |ip|
95
+ bp = Breakpoint.for_ip(meth, ip, opts)
96
+ bp.scoped!(@frame.scope)
97
+ bp.activate
98
+ bps << bp
99
+ end
100
+ @step_brkpts += bps
101
+ first_bp = bps[0]
102
+ bps[1..-1].each do |bp|
103
+ first_bp.related_with(bp)
104
+ end
105
+ return first_bp
106
+ end
107
+
108
+ def set_breakpoints_on_return_between(meth, start_ip, fin_ip)
109
+ ips = ISeq::yield_or_return_between(meth, start_ip, fin_ip)
110
+ if ips.empty?
111
+ errmsg '"ret" or "yield_stack" opcode not found'
112
+ return []
113
+ end
114
+
115
+ bp1 = Breakpoint.for_ip(meth, ips[0],
116
+ { :event => 'return',
117
+ :temp => true})
118
+ bp1.scoped!(@frame.scope)
119
+ bp1.activate
120
+ result = [bp1]
121
+
122
+ 1.upto(ips.size-1) do |i|
123
+ bp2 = Breakpoint.for_ip(meth, ips[i],
124
+ { :event => 'return',
125
+ :temp => true})
126
+ bp2.scoped!(@frame.scope)
127
+ bp1.related_with(bp2)
128
+ bp2.activate
129
+ result << bp2
130
+ end
131
+ @step_brkpts += result
132
+ return result
133
+ end
134
+ end
135
+ end