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
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