rbx-trepanning 0.0.1-universal-rubinius

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. data/ChangeLog +376 -0
  2. data/LICENSE +25 -0
  3. data/NEWS +2 -0
  4. data/README.textile +28 -0
  5. data/Rakefile +165 -0
  6. data/THANKS +14 -0
  7. data/app/breakpoint.rb +218 -0
  8. data/app/breakpoint.rbc +3564 -0
  9. data/app/brkptmgr.rb +138 -0
  10. data/app/brkptmgr.rbc +2827 -0
  11. data/app/default.rb +61 -0
  12. data/app/default.rbc +1011 -0
  13. data/app/display.rb +35 -0
  14. data/app/display.rbc +968 -0
  15. data/app/frame.rb +98 -0
  16. data/app/frame.rbc +1808 -0
  17. data/app/irb.rb +112 -0
  18. data/app/irb.rbc +2111 -0
  19. data/app/iseq.rb +95 -0
  20. data/app/iseq.rbc +1801 -0
  21. data/app/method.rb +173 -0
  22. data/app/method.rbc +2492 -0
  23. data/app/mock.rb +13 -0
  24. data/app/mock.rbc +398 -0
  25. data/app/options.rb +123 -0
  26. data/app/options.rbc +2183 -0
  27. data/app/run.rb +86 -0
  28. data/app/run.rbc +1244 -0
  29. data/app/util.rb +49 -0
  30. data/app/util.rbc +1144 -0
  31. data/app/validate.rb +30 -0
  32. data/app/validate.rbc +676 -0
  33. data/bin/trepan.compiled.rbc +1043 -0
  34. data/bin/trepanx +63 -0
  35. data/bin/trepanx.compiled.rbc +985 -0
  36. data/interface/base_intf.rb +95 -0
  37. data/interface/base_intf.rbc +1742 -0
  38. data/interface/script.rb +104 -0
  39. data/interface/script.rbc +1642 -0
  40. data/interface/user.rb +91 -0
  41. data/interface/user.rbc +1418 -0
  42. data/io/base_io.rb +94 -0
  43. data/io/base_io.rbc +1404 -0
  44. data/io/input.rb +112 -0
  45. data/io/input.rbc +1979 -0
  46. data/io/null_output.rb +42 -0
  47. data/io/null_output.rbc +730 -0
  48. data/io/string_array.rb +156 -0
  49. data/io/string_array.rbc +2466 -0
  50. data/lib/trepanning.rb +398 -0
  51. data/lib/trepanning.rbc +6661 -0
  52. data/processor/breakpoint.rb +161 -0
  53. data/processor/command/alias.rb +55 -0
  54. data/processor/command/backtrace.rb +46 -0
  55. data/processor/command/base/cmd.rb +124 -0
  56. data/processor/command/base/subcmd.rb +213 -0
  57. data/processor/command/base/submgr.rb +179 -0
  58. data/processor/command/base/subsubcmd.rb +103 -0
  59. data/processor/command/base/subsubmgr.rb +184 -0
  60. data/processor/command/break.rb +100 -0
  61. data/processor/command/continue.rb +82 -0
  62. data/processor/command/delete.rb +30 -0
  63. data/processor/command/directory.rb +43 -0
  64. data/processor/command/disassemble.rb +103 -0
  65. data/processor/command/down.rb +54 -0
  66. data/processor/command/eval.rb +31 -0
  67. data/processor/command/exit.rb +58 -0
  68. data/processor/command/finish.rb +78 -0
  69. data/processor/command/frame.rb +89 -0
  70. data/processor/command/help.rb +146 -0
  71. data/processor/command/info.rb +28 -0
  72. data/processor/command/info_subcmd/breakpoints.rb +75 -0
  73. data/processor/command/info_subcmd/file.rb +153 -0
  74. data/processor/command/info_subcmd/method.rb +71 -0
  75. data/processor/command/info_subcmd/program.rb +59 -0
  76. data/processor/command/info_subcmd/variables.rb +40 -0
  77. data/processor/command/irb.rb +96 -0
  78. data/processor/command/kill.rb +70 -0
  79. data/processor/command/list.rb +296 -0
  80. data/processor/command/next.rb +66 -0
  81. data/processor/command/nexti.rb +59 -0
  82. data/processor/command/pr.rb +38 -0
  83. data/processor/command/ps.rb +40 -0
  84. data/processor/command/restart.rb +60 -0
  85. data/processor/command/set.rb +47 -0
  86. data/processor/command/set_subcmd/auto.rb +28 -0
  87. data/processor/command/set_subcmd/auto_subcmd/dis.rb +33 -0
  88. data/processor/command/set_subcmd/auto_subcmd/eval.rb +54 -0
  89. data/processor/command/set_subcmd/auto_subcmd/irb.rb +34 -0
  90. data/processor/command/set_subcmd/auto_subcmd/list.rb +34 -0
  91. data/processor/command/set_subcmd/basename.rb +26 -0
  92. data/processor/command/set_subcmd/debug.rb +27 -0
  93. data/processor/command/set_subcmd/debug_subcmd/dbgr.rb +36 -0
  94. data/processor/command/set_subcmd/debug_subcmd/skip.rb +23 -0
  95. data/processor/command/set_subcmd/debug_subcmd/step.rb +23 -0
  96. data/processor/command/set_subcmd/different.rb +60 -0
  97. data/processor/command/set_subcmd/hidelevel.rb +63 -0
  98. data/processor/command/set_subcmd/kernelstep.rb +61 -0
  99. data/processor/command/set_subcmd/max.rb +29 -0
  100. data/processor/command/set_subcmd/max_subcmd/list.rb +49 -0
  101. data/processor/command/set_subcmd/max_subcmd/stack.rb +50 -0
  102. data/processor/command/set_subcmd/max_subcmd/string.rb +54 -0
  103. data/processor/command/set_subcmd/max_subcmd/width.rb +49 -0
  104. data/processor/command/set_subcmd/substitute.rb +25 -0
  105. data/processor/command/set_subcmd/substitute_subcmd/path.rb +56 -0
  106. data/processor/command/set_subcmd/trace.rb +37 -0
  107. data/processor/command/set_subcmd/trace_subcmd/print.rb +57 -0
  108. data/processor/command/show.rb +27 -0
  109. data/processor/command/show_subcmd/alias.rb +43 -0
  110. data/processor/command/show_subcmd/args.rb +26 -0
  111. data/processor/command/show_subcmd/auto.rb +28 -0
  112. data/processor/command/show_subcmd/auto_subcmd/dis.rb +37 -0
  113. data/processor/command/show_subcmd/auto_subcmd/eval.rb +28 -0
  114. data/processor/command/show_subcmd/auto_subcmd/irb.rb +23 -0
  115. data/processor/command/show_subcmd/auto_subcmd/list.rb +22 -0
  116. data/processor/command/show_subcmd/basename.rb +22 -0
  117. data/processor/command/show_subcmd/debug.rb +27 -0
  118. data/processor/command/show_subcmd/debug_subcmd/dbgr.rb +21 -0
  119. data/processor/command/show_subcmd/debug_subcmd/skip.rb +22 -0
  120. data/processor/command/show_subcmd/debug_subcmd/step.rb +22 -0
  121. data/processor/command/show_subcmd/different.rb +27 -0
  122. data/processor/command/show_subcmd/hidelevel.rb +42 -0
  123. data/processor/command/show_subcmd/kernelstep.rb +37 -0
  124. data/processor/command/show_subcmd/max.rb +30 -0
  125. data/processor/command/show_subcmd/max_subcmd/list.rb +38 -0
  126. data/processor/command/show_subcmd/max_subcmd/stack.rb +36 -0
  127. data/processor/command/show_subcmd/max_subcmd/string.rb +42 -0
  128. data/processor/command/show_subcmd/max_subcmd/width.rb +37 -0
  129. data/processor/command/show_subcmd/trace.rb +29 -0
  130. data/processor/command/show_subcmd/trace_subcmd/print.rb +38 -0
  131. data/processor/command/source.rb +83 -0
  132. data/processor/command/step.rb +41 -0
  133. data/processor/command/tbreak.rb +19 -0
  134. data/processor/command/unalias.rb +44 -0
  135. data/processor/command/up.rb +87 -0
  136. data/processor/default.rb +56 -0
  137. data/processor/disassemble.rb +32 -0
  138. data/processor/eval.rb +96 -0
  139. data/processor/frame.rb +211 -0
  140. data/processor/help.rb +72 -0
  141. data/processor/hook.rb +133 -0
  142. data/processor/load_cmds.rb +101 -0
  143. data/processor/location.rb +128 -0
  144. data/processor/main.rb +394 -0
  145. data/processor/mock.rb +137 -0
  146. data/processor/msg.rb +28 -0
  147. data/processor/running.rb +230 -0
  148. data/processor/stepping.rb +115 -0
  149. data/processor/subcmd.rb +160 -0
  150. data/processor/validate.rb +355 -0
  151. data/test/data/enable.right +36 -0
  152. data/test/data/fname-with-blank.cmd +6 -0
  153. data/test/data/fname-with-blank.right +1 -0
  154. data/test/data/quit-Xdebug.right +3 -0
  155. data/test/data/quit.cmd +5 -0
  156. data/test/data/quit.right +0 -0
  157. data/test/example/fname with blank.rb +1 -0
  158. data/test/example/gcd-xx.rb +18 -0
  159. data/test/example/gcd.rb +19 -0
  160. data/test/example/gcd1.rb +24 -0
  161. data/test/example/null.rb +1 -0
  162. data/test/example/thread1.rb +3 -0
  163. data/test/functional/fn_helper.rb +112 -0
  164. data/test/functional/test-break-name.rb +52 -0
  165. data/test/functional/test-break.rb +51 -0
  166. data/test/functional/test-finish.rb +70 -0
  167. data/test/functional/test-fn_helper.rb +43 -0
  168. data/test/functional/test-list.rb +55 -0
  169. data/test/functional/test-next-bug.rb +49 -0
  170. data/test/functional/test-next.rb +101 -0
  171. data/test/functional/test-step.rb +272 -0
  172. data/test/functional/test-step2.rb +35 -0
  173. data/test/functional/test-tbreak.rb +41 -0
  174. data/test/integration/file-diff.rb +89 -0
  175. data/test/integration/helper.rb +78 -0
  176. data/test/integration/test-fname-with-blank.rb +12 -0
  177. data/test/integration/test-quit.rb +25 -0
  178. data/test/unit/cmd-helper.rb +46 -0
  179. data/test/unit/test-app-brkpt.rb +30 -0
  180. data/test/unit/test-app-brkptmgr.rb +51 -0
  181. data/test/unit/test-app-iseq.rb +49 -0
  182. data/test/unit/test-app-method.rb +54 -0
  183. data/test/unit/test-app-options.rb +61 -0
  184. data/test/unit/test-app-run.rb +16 -0
  185. data/test/unit/test-app-util.rb +28 -0
  186. data/test/unit/test-app-validate.rb +18 -0
  187. data/test/unit/test-base-subcmd.rb +61 -0
  188. data/test/unit/test-bin-trepanx.rb +48 -0
  189. data/test/unit/test-cmd-alias.rb +49 -0
  190. data/test/unit/test-cmd-break.rb +23 -0
  191. data/test/unit/test-cmd-exit.rb +27 -0
  192. data/test/unit/test-cmd-help.rb +101 -0
  193. data/test/unit/test-cmd-kill.rb +48 -0
  194. data/test/unit/test-intf-user.rb +46 -0
  195. data/test/unit/test-io-input.rb +27 -0
  196. data/test/unit/test-proc-eval.rb +37 -0
  197. data/test/unit/test-proc-frame.rb +79 -0
  198. data/test/unit/test-proc-help.rb +16 -0
  199. data/test/unit/test-proc-hook.rb +30 -0
  200. data/test/unit/test-proc-load_cmds.rb +41 -0
  201. data/test/unit/test-proc-location.rb +48 -0
  202. data/test/unit/test-proc-main.rb +96 -0
  203. data/test/unit/test-proc-validate.rb +91 -0
  204. data/test/unit/test-subcmd-help.rb +51 -0
  205. metadata +337 -0
data/lib/trepanning.rb ADDED
@@ -0,0 +1,398 @@
1
+ require 'readline'
2
+ require 'compiler/iseq'
3
+
4
+ require 'rubygems'; require 'require_relative'
5
+ require_relative '../app/frame'
6
+ require_relative '../app/util' # get_dollar_0
7
+ require_relative '../processor/main'
8
+ require_relative '../app/breakpoint'
9
+ require_relative '../app/default' # default debugger settings
10
+ require_relative '../app/breakpoint'
11
+ require_relative '../app/display' # FIXME: remove
12
+ require_relative '../interface/user' # user interface (includes I/O)
13
+ require_relative '../io/null_output'
14
+
15
+ #
16
+ # The Rubinius Trepan debugger.
17
+ #
18
+ # This debugger is wired into the debugging APIs provided by Rubinius.
19
+ #
20
+
21
+ class Trepan
22
+ VERSION = '0.0.1'
23
+
24
+ attr_accessor :breakpoint # Breakpoint. The current breakpoint we are
25
+ # stopped at or nil if none.
26
+ attr_accessor :intf # Array. The way the outside world
27
+ # interfaces with us. An array, so that
28
+ # interfaces with us. An array, so that
29
+ # interfaces can be stacked.
30
+ attr_accessor :restart_argv # How to restart us, empty or nil.
31
+ # Note: restart_argv is typically C's
32
+ # **argv, not Ruby's ARGV. So
33
+ # restart_argv[0] is $0.
34
+ attr_reader :settings # Hash[:symbol] of things you can configure
35
+ attr_reader :deferred_breakpoints
36
+ attr_reader :processor
37
+
38
+ # Used to try and show the source for the kernel. Should
39
+ # mostly work, but it's a hack.
40
+ DBGR_DIR = File.dirname(RequireRelative.abs_file)
41
+ ROOT_DIR = File.expand_path(File.join(DBGR_DIR, "/.."))
42
+
43
+ include Trepan::Display # FIXME: remove
44
+
45
+ # Create a new debugger object. The debugger starts up a thread
46
+ # which is where the command line interface executes from. Other
47
+ # threads that you wish to debug are told that their debugging
48
+ # thread is the debugger thread. This is how the debugger is handed
49
+ # control of execution.
50
+ #
51
+ def initialize(settings={})
52
+ @breakpoint = nil
53
+ @settings = Trepanning::DEFAULT_SETTINGS.merge(settings)
54
+ @input ||= @settings[:input]
55
+ @output ||= @settings[:output]
56
+
57
+ @processor = CmdProcessor.new(self)
58
+
59
+ @intf = [Trepan::UserInterface.new(@input, @output)]
60
+ @settings[:cmdfiles].each do |cmdfile|
61
+ add_command_file(cmdfile)
62
+ end if @settings.member?(:cmdfiles)
63
+ Dir.chdir(@settings[:initial_dir]) if @settings[:initial_dir]
64
+ @restart_argv = @settings[:restart_argv]
65
+
66
+ ## FIXME: put in fn
67
+ @processor.dbgr = self
68
+ ## m = Rubinius::Loader.method(:debugger).executable.inspect
69
+ meth = Rubinius::VM.backtrace(0)[0].method
70
+ @processor.ignore_methods[meth] = 'next'
71
+ @processor.ignore_methods[method(:debugger)] = 'step'
72
+
73
+ @thread = nil
74
+ @frames = []
75
+ ## FIXME: Delete these and use the ones in processor/default instead.
76
+ @variables = {
77
+ :show_bytecode => false,
78
+ :highlight => false
79
+ }
80
+
81
+ @loaded_hook = proc { |file|
82
+ check_deferred_breakpoints
83
+ }
84
+
85
+ @added_hook = proc { |mod, name, exec|
86
+ check_deferred_breakpoints
87
+ }
88
+
89
+ # Use a few Rubinius specific hooks to trigger checking
90
+ # for deferred breakpoints.
91
+
92
+ Rubinius::CodeLoader.loaded_hook.add @loaded_hook
93
+ Rubinius.add_method_hook.add @added_hook
94
+
95
+ @deferred_breakpoints = []
96
+
97
+ @history_path = File.expand_path("~/.trepanx")
98
+
99
+ if File.exists?(@history_path)
100
+ File.readlines(@history_path).each do |line|
101
+ Readline::HISTORY << line.strip
102
+ end
103
+ @history_io = File.new(@history_path, "a")
104
+ else
105
+ @history_io = File.new(@history_path, "w")
106
+ end
107
+
108
+ @history_io.sync = true
109
+
110
+ @root_dir = ROOT_DIR
111
+
112
+ # Run user debugger command startup files.
113
+ add_startup_files unless @settings[:nx]
114
+ add_command_file(@settings[:restore_profile]) if
115
+ @settings[:restore_profile] && File.readable?(@settings[:restore_profile])
116
+ end
117
+
118
+ ## HACK to skip over loader code. Until I find something better...
119
+ def skip_loader
120
+ cmds =
121
+ if @settings[:skip_loader] == :Xdebug
122
+ ['continue Rubinius::CodeLoader#load_script',
123
+ 'continue 67',
124
+ # 'set kernelstep off', # eventually would like 'on'
125
+ 'step', 'set hidelevel -1'
126
+ ]
127
+ else
128
+ ['next', 'next',
129
+ # 'set kernelstep off', # eventually would like 'on'
130
+ 'set hidelevel -1',
131
+ 'step', ]
132
+ end
133
+
134
+ input = Trepan::StringArrayInput.open(cmds)
135
+ startup = Trepan::ScriptInterface.new('startup',
136
+ Trepan::OutputNull.new(nil),
137
+ :input => input)
138
+ @intf << startup
139
+ end
140
+
141
+
142
+ attr_reader :variables, :current_frame, :breakpoints
143
+ attr_reader :vm_locations, :history_io, :debugee_thread
144
+
145
+ def self.global(settings={})
146
+ @global ||= new(settings)
147
+ end
148
+
149
+ def self.start(settings={})
150
+ settings = {:immediate => false, :offset => 1}.merge(settings)
151
+ global(settings).start(settings)
152
+ end
153
+
154
+ # This is simplest API point. This starts up the debugger in the caller
155
+ # of this method to begin debugging.
156
+ #
157
+ def self.here(settings={})
158
+ global(settings).start(:offset => 1)
159
+ end
160
+
161
+ # Startup the debugger, skipping back +offset+ frames. This lets you start
162
+ # the debugger straight into callers method.
163
+ #
164
+ def start(settings = {:immediate => false})
165
+ @settings = @settings.merge(settings)
166
+ skip_loader if @settings[:skip_loader]
167
+ spinup_thread
168
+ @debugee_thread = @thread
169
+ if @settings[:hide_level]
170
+ @processor.hidelevels[@thread] = @settings[:hide_level]
171
+ end
172
+
173
+ # Feed info to the debugger thread!
174
+ locs = Rubinius::VM.backtrace(@settings[:offset] + 1, true)
175
+
176
+ method = Rubinius::CompiledMethod.of_sender
177
+
178
+ event = settings[:immediate] ? 'debugger-call' : 'start'
179
+ bp = Trepanning::Breakpoint.new('<start>', method, 0, 0, 0,
180
+ {:event => event}
181
+ )
182
+ channel = Rubinius::Channel.new
183
+
184
+ @local_channel.send Rubinius::Tuple[bp, Thread.current, channel, locs]
185
+
186
+ # wait for the debugger to release us
187
+ channel.receive
188
+
189
+ Thread.current.set_debugger_thread @thread
190
+ self
191
+ end
192
+
193
+ def stop(settings = {})
194
+ # Nothing for now...
195
+ end
196
+
197
+ def add_command_file(cmdfile, stderr=$stderr)
198
+ unless File.readable?(cmdfile)
199
+ if File.exists?(cmdfile)
200
+ stderr.puts "Command file '#{cmdfile}' is not readable."
201
+ return
202
+ else
203
+ stderr.puts "Command file '#{cmdfile}' does not exist."
204
+ stderr.puts caller
205
+ return
206
+ end
207
+ end
208
+ @intf << Trepan::ScriptInterface.new(cmdfile, @output)
209
+ end
210
+
211
+ def add_startup_files()
212
+ seen = {}
213
+ cwd_initfile = File.join('.', Trepanning::CMD_INITFILE_BASE)
214
+ [cwd_initfile, Trepanning::CMD_INITFILE].each do |initfile|
215
+ full_initfile_path = File.expand_path(initfile)
216
+ next if seen[full_initfile_path]
217
+ add_command_file(full_initfile_path) if File.readable?(full_initfile_path)
218
+ seen[full_initfile_path] = true
219
+ end
220
+ end
221
+
222
+ # Stop and wait for a debuggee thread to send us info about
223
+ # stopping at a breakpoint.
224
+ #
225
+ def listen(step_into=false)
226
+ @breakpoint = nil
227
+ while true
228
+ if @channel
229
+ if step_into
230
+ @channel << :step
231
+ else
232
+ @channel << true
233
+ end
234
+ end
235
+
236
+ # Wait for someone to stop
237
+ @breakpoint, @debugee_thread, @channel, @vm_locations =
238
+ @local_channel.receive
239
+
240
+ # Uncache all frames since we stopped at a new place
241
+ @frames = []
242
+
243
+ set_frame(0)
244
+
245
+ if @breakpoint
246
+ # Some breakpoints are frame specific. Check for this. hit!
247
+ # also removes the breakpoint if it was temporary and hit.
248
+ break if @breakpoint.hit!(@vm_locations.first.variables)
249
+ else
250
+ @processor.step_bp.remove! if @processor.step_bp
251
+ break
252
+ end
253
+ end
254
+
255
+ event =
256
+ if @breakpoint
257
+ @breakpoint.event || 'brkpt'
258
+ else
259
+ # Evan assures me that the only way the breakpoint can be nil
260
+ # is if we are stepping and enter a function.
261
+ 'step-call'
262
+ end
263
+ @processor.instance_variable_set('@event', event)
264
+
265
+ if @variables[:show_bytecode]
266
+ decode_one
267
+ end
268
+
269
+ end
270
+
271
+ def frame(num)
272
+ @frames[num] ||= Frame.new(self, num, @vm_locations[num])
273
+ end
274
+
275
+ def set_frame(num)
276
+ @current_frame = frame(num)
277
+ end
278
+
279
+ def each_frame(start=0)
280
+ start = start.number if start.kind_of?(Frame)
281
+
282
+ start.upto(@vm_locations.size-1) do |idx|
283
+ yield frame(idx)
284
+ end
285
+ end
286
+
287
+ def add_deferred_breakpoint(klass_name, which, name, line)
288
+ dbp = Trepanning::DeferredBreakpoint.new(self, @current_frame, klass_name, which, name,
289
+ line, @deferred_breakpoints)
290
+ @deferred_breakpoints << dbp
291
+ # @processor.brkpts << dbp
292
+ end
293
+
294
+ def check_deferred_breakpoints
295
+ @deferred_breakpoints.delete_if do |bp|
296
+ bp.resolve!
297
+ end
298
+ end
299
+
300
+ def send_between(exec, start, fin)
301
+ ss = Rubinius::InstructionSet.opcodes_map[:send_stack]
302
+ sm = Rubinius::InstructionSet.opcodes_map[:send_method]
303
+ sb = Rubinius::InstructionSet.opcodes_map[:send_stack_with_block]
304
+
305
+ iseq = exec.iseq
306
+
307
+ fin = iseq.size if fin < 0
308
+
309
+ i = start
310
+ while i < fin
311
+ op = iseq[i]
312
+ case op
313
+ when ss, sm, sb
314
+ return exec.literals[iseq[i + 1]]
315
+ else
316
+ op = Rubinius::InstructionSet[op]
317
+ i += (op.arg_count + 1)
318
+ end
319
+ end
320
+
321
+ return nil
322
+ end
323
+
324
+ def show_code(line=@current_frame.line)
325
+ path = @current_frame.method.active_path
326
+ str = @processor.line_at(path, line)
327
+ unless str.nil?
328
+ # if @variables[:highlight]
329
+ # fin = @current_frame.method.first_ip_on_line(line + 1)
330
+ # name = send_between(@current_frame.method, @current_frame.ip, fin)
331
+
332
+ # if name
333
+ # str = str.gsub name.to_s, "\033[0;4m#{name}\033[0m"
334
+ # end
335
+ # end
336
+ # info "#{line}: #{str}"
337
+ else
338
+ show_bytecode(line)
339
+ end
340
+ end
341
+
342
+ def decode_one
343
+ ip = @current_frame.next_ip
344
+
345
+ meth = @current_frame.method
346
+ decoder = Rubinius::InstructionDecoder.new(meth.iseq)
347
+ partial = decoder.decode_between(ip, ip+1)
348
+
349
+ partial.each do |ins|
350
+ op = ins.shift
351
+
352
+ ins.each_index do |i|
353
+ case op.args[i]
354
+ when :literal
355
+ ins[i] = meth.literals[ins[i]].inspect
356
+ when :local
357
+ if meth.local_names
358
+ ins[i] = meth.local_names[ins[i]]
359
+ end
360
+ end
361
+ end
362
+
363
+ display "ip #{ip} = #{op.opcode} #{ins.join(', ')}"
364
+ end
365
+ end
366
+
367
+ def spinup_thread
368
+ return if @thread
369
+
370
+ @local_channel = Rubinius::Channel.new
371
+
372
+ @thread = Thread.new do
373
+ begin
374
+ listen
375
+ rescue Exception => e
376
+ e.render("Listening")
377
+ break
378
+ end
379
+
380
+ @processor.process_commands
381
+
382
+ end
383
+
384
+ @thread.setup_control!(@local_channel)
385
+ end
386
+
387
+ private :spinup_thread
388
+
389
+ end
390
+
391
+ module Kernel
392
+ # A simpler way of calling Trepan.start
393
+ def debugger(settings = {})
394
+ settings = {:immediate => false, :offset => 2}.merge(settings)
395
+ Trepan.start(settings)
396
+ end
397
+ alias breakpoint debugger unless respond_to?(:breakpoint)
398
+ end