rbx-trepanning 0.0.6-universal-rubinius-1.2 → 0.0.7-universal-rubinius-1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. data/.gitignore +5 -0
  2. data/ChangeLog +161 -0
  3. data/Makefile +13 -0
  4. data/NEWS +11 -0
  5. data/Rakefile +6 -5
  6. data/app/.gitignore +2 -0
  7. data/app/breakpoint.rb +53 -36
  8. data/app/brkptmgr.rb +10 -0
  9. data/app/complete.rb +29 -2
  10. data/app/condition.rb +22 -0
  11. data/app/default.rb +1 -0
  12. data/app/eventbuffer.rb +147 -0
  13. data/app/frame.rb +3 -1
  14. data/app/options.rb +2 -2
  15. data/app/run.rb +5 -3
  16. data/bin/.gitignore +2 -0
  17. data/data/.gitignore +2 -0
  18. data/doc/.gitignore +1 -0
  19. data/doc/debugger.html +108 -0
  20. data/interface/.gitignore +2 -0
  21. data/interface/user.rb +8 -7
  22. data/io/.gitignore +3 -0
  23. data/io/input.rb +14 -8
  24. data/lib/.gitignore +2 -0
  25. data/lib/trepanning.rb +25 -33
  26. data/processor/.gitignore +3 -0
  27. data/processor/Makefile +7 -0
  28. data/processor/breakpoint.rb +4 -0
  29. data/processor/command/.gitignore +2 -0
  30. data/processor/command/backtrace.rb +5 -0
  31. data/processor/command/base/.gitignore +2 -0
  32. data/processor/command/base/subcmd.rb +2 -1
  33. data/processor/command/base/subsubcmd.rb +23 -1
  34. data/processor/command/base/subsubmgr.rb +2 -1
  35. data/processor/command/complete.rb +2 -1
  36. data/processor/command/condition.rb +62 -0
  37. data/processor/command/down.rb +4 -4
  38. data/processor/command/eval.rb +14 -6
  39. data/processor/command/exit.rb +8 -7
  40. data/processor/command/frame.rb +6 -2
  41. data/processor/command/info_subcmd/.gitignore +3 -0
  42. data/processor/command/info_subcmd/breakpoints.rb +8 -0
  43. data/processor/command/info_subcmd/files.rb +1 -1
  44. data/processor/command/info_subcmd/line.rb +1 -1
  45. data/processor/command/info_subcmd/ruby.rb +1 -1
  46. data/processor/command/kill.rb +21 -10
  47. data/processor/command/macro.rb +15 -23
  48. data/processor/command/set_subcmd/.gitignore +2 -0
  49. data/processor/command/set_subcmd/auto_subcmd/.gitignore +2 -0
  50. data/processor/command/set_subcmd/debug_subcmd/.gitignore +2 -0
  51. data/processor/command/set_subcmd/different.rb +2 -0
  52. data/processor/command/set_subcmd/max_subcmd/.gitignore +2 -0
  53. data/processor/command/set_subcmd/substitute_subcmd/.gitignore +3 -0
  54. data/processor/command/set_subcmd/trace_subcmd/.gitignore +2 -0
  55. data/processor/command/set_subcmd/trace_subcmd/buffer.rb +42 -0
  56. data/processor/command/set_subcmd/trace_subcmd/print.rb +13 -29
  57. data/processor/command/show_subcmd/.gitignore +3 -0
  58. data/processor/command/show_subcmd/alias.rb +7 -3
  59. data/processor/command/show_subcmd/auto_subcmd/.gitignore +3 -0
  60. data/processor/command/show_subcmd/auto_subcmd/irb.rb +1 -1
  61. data/processor/command/show_subcmd/debug_subcmd/.gitignore +3 -0
  62. data/processor/command/show_subcmd/macro.rb +62 -0
  63. data/processor/command/show_subcmd/max_subcmd/.gitignore +2 -0
  64. data/processor/command/show_subcmd/trace_subcmd/.gitignore +2 -0
  65. data/processor/command/show_subcmd/trace_subcmd/buffer.rb +64 -0
  66. data/processor/command/show_subcmd/trace_subcmd/print.rb +5 -20
  67. data/processor/command/source.rb +7 -0
  68. data/processor/command/up.rb +12 -8
  69. data/processor/eventbuf.rb +101 -0
  70. data/processor/frame.rb +19 -1
  71. data/processor/hook.rb +2 -2
  72. data/processor/load_cmds.rb +57 -49
  73. data/processor/location.rb +40 -0
  74. data/processor/main.rb +27 -26
  75. data/processor/msg.rb +17 -0
  76. data/processor/stepping.rb +21 -1
  77. data/processor/validate.rb +1 -0
  78. data/rbx-trepanning.gemspec +40 -0
  79. data/sample/.gitignore +2 -0
  80. data/test/data/.gitignore +1 -0
  81. data/test/example/.gitignore +2 -0
  82. data/test/functional/.gitignore +3 -0
  83. data/test/functional/test-finish.rb +2 -2
  84. data/test/integration/.gitignore +3 -0
  85. data/test/unit/.gitignore +3 -0
  86. data/test/unit/cmd-helper.rb +6 -2
  87. data/test/unit/test-app-brkpt.rb +14 -12
  88. data/test/unit/test-app-complete.rb +39 -0
  89. data/test/unit/test-app-condition.rb +18 -0
  90. data/test/unit/test-app-options.rb +8 -1
  91. data/test/unit/test-base-subsubcmd.rb +21 -0
  92. data/test/unit/test-cmd-finish.rb +4 -0
  93. data/test/unit/test-completion.rb +11 -6
  94. data/test/unit/test-proc-load_cmds.rb +2 -2
  95. metadata +295 -218
  96. data/app/breakpoint.rbc +0 -3551
  97. data/app/brkptmgr.rbc +0 -2903
  98. data/app/client.rbc +0 -1225
  99. data/app/complete.rbc +0 -1288
  100. data/app/default.rbc +0 -1132
  101. data/app/display.rbc +0 -2578
  102. data/app/frame.rbc +0 -1808
  103. data/app/irb.rbc +0 -2094
  104. data/app/iseq.rbc +0 -2192
  105. data/app/llvm.rbc +0 -2478
  106. data/app/method.rbc +0 -2492
  107. data/app/method_name.rbc +0 -2467
  108. data/app/mock.rbc +0 -398
  109. data/app/options.rbc +0 -2898
  110. data/app/rbx-llvm.rbc +0 -2478
  111. data/app/run.rbc +0 -1244
  112. data/app/util.rbc +0 -1146
  113. data/app/validate.rbc +0 -676
  114. data/bin/trepan.compiled.rbc +0 -1043
  115. data/bin/trepanx.compiled.rbc +0 -1049
  116. data/data/irbrc.compiled.rbc +0 -640
  117. data/interface/base_intf.rbc +0 -1899
  118. data/interface/client.rbc +0 -1072
  119. data/interface/comcodes.rbc +0 -385
  120. data/interface/script.rbc +0 -1642
  121. data/interface/server.rbc +0 -2213
  122. data/interface/user.rbc +0 -2867
  123. data/io/base_io.rbc +0 -2111
  124. data/io/input.rbc +0 -2528
  125. data/io/null_output.rbc +0 -730
  126. data/io/string_array.rbc +0 -2466
  127. data/io/tcpclient.rbc +0 -2419
  128. data/io/tcpfns.rbc +0 -694
  129. data/io/tcpserver.rbc +0 -2638
  130. data/lib/trepanning.rbc +0 -7705
  131. data/lib/trepanning2.rb +0 -441
  132. data/sample/list-terminal-colors.rbc +0 -2318
  133. data/sample/rocky-trepanx-colors.rbc +0 -530
  134. data/test/data/step-bug.cmd +0 -11
  135. data/test/data/step-bug.right +0 -3
  136. data/test/example/step-bug.rb +0 -14
  137. data/test/integration/skip-test-step-bug.rb +0 -17
data/lib/trepanning2.rb DELETED
@@ -1,441 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
- require 'readline'
4
- require 'compiler/iseq'
5
-
6
- require 'rubygems'; require 'require_relative'
7
- require_relative '../app/frame'
8
- require_relative '../app/util' # get_dollar_0
9
- require_relative '../processor/main'
10
- require_relative '../app/breakpoint'
11
- require_relative '../app/default' # default debugger settings
12
- require_relative '../app/breakpoint'
13
- require_relative '../interface/user' # user interface (includes I/O)
14
- require_relative '../interface/client' # client interface (remote debugging)
15
- require_relative '../interface/server' # server interface (remote debugging)
16
- require_relative '../io/null_output'
17
-
18
- #
19
- # The Rubinius Trepan debugger.
20
- #
21
- # This debugger is wired into the debugging APIs provided by Rubinius.
22
- #
23
-
24
- class Trepan
25
- attr_accessor :breakpoint # Breakpoint. The current breakpoint we are
26
- # stopped at or nil if none.
27
- attr_accessor :intf # Array. The way the outside world
28
- # interfaces with us. An array, so that
29
- # interfaces with us. An array, so that
30
- # interfaces can be stacked.
31
- attr_accessor :restart_argv # How to restart us, empty or nil.
32
- # Note: restart_argv is typically C's
33
- # **argv, not Ruby's ARGV. So
34
- # restart_argv[0] is $0.
35
- attr_reader :settings # Hash[:symbol] of things you can configure
36
- attr_reader :deferred_breakpoints
37
- attr_reader :processor
38
-
39
- # Create a new debugger object. The debugger starts up a thread
40
- # which is where the command line interface executes from. Other
41
- # threads that you wish to debug are told that their debugging
42
- # thread is the debugger thread. This is how the debugger is handed
43
- # control of execution.
44
- #
45
- def initialize(settings={})
46
- @breakpoint = nil
47
- @settings = DEFAULT_SETTINGS.merge(settings)
48
- @input = @settings[:input] || STDIN
49
- @output = @settings[:output] || STDOUT
50
-
51
- cmdproc_settings = {:highlight => @settings[:highlight]}
52
-
53
- @processor = CmdProcessor.new(self, cmdproc_settings)
54
- completion_proc = Proc.new do |str|
55
- completed_ary = @processor.complete(Readline.line_buffer, true)
56
- Readline.line_buffer = '' unless completed_ary.empty?
57
- completed_ary
58
- end
59
-
60
- @intf =
61
- if @settings[:server]
62
- opts = Trepan::ServerInterface::DEFAULT_INIT_CONNECTION_OPTS.dup
63
- opts[:port] = @settings[:port] if @settings[:port]
64
- opts[:host] = @settings[:host] if @settings[:host]
65
- puts("starting debugger in out-of-process mode port at " +
66
- "#{opts[:host]}:#{opts[:port]}")
67
- [Trepan::ServerInterface.new(nil, nil, opts)]
68
- elsif @settings[:client]
69
- opts = Trepan::ClientInterface::DEFAULT_INIT_CONNECTION_OPTS.dup
70
- opts[:port] = @settings[:port] if @settings[:port]
71
- opts[:host] = @settings[:host] if @settings[:host]
72
- opts[:complete] = completion_proc
73
- [Trepan::ClientInterface.new(nil, nil, nil, nil, opts)]
74
- else
75
- opts = {:complete => completion_proc}
76
- [Trepan::UserInterface.new(@input, @output, opts)]
77
- end
78
-
79
- process_cmdfile_setting(@settings)
80
- if @settings[:initial_dir]
81
- Dir.chdir(@settings[:initial_dir])
82
- else
83
- @settings[:initial_dir] = Dir.pwd
84
- end
85
- @initial_dir = @settings[:initial_dir]
86
- @restart_argv = @settings[:restart_argv]
87
-
88
- ## FIXME: Delete these and use the ones in processor/default instead.
89
- @variables = {
90
- :show_bytecode => false,
91
- }
92
-
93
- @history_path = File.expand_path("~/.trepanx")
94
-
95
- if File.exists?(@history_path)
96
- File.readlines(@history_path).each_with_index do |line, i|
97
- break if i > 50 # FIXME: remove constant 50
98
- Readline::HISTORY << line.strip
99
- end
100
- @history_io = File.new(@history_path, "a")
101
- else
102
- @history_io = File.new(@history_path, "w")
103
- end
104
-
105
- @history_io.sync = true
106
-
107
- @processor.dbgr = self
108
- @deferred_breakpoints = []
109
- @thread = nil
110
- @frames = []
111
-
112
- unless @settings[:client]
113
- ## FIXME: put in fn
114
- ## m = Rubinius::Loader.method(:debugger).executable.inspect
115
- meth = Rubinius::VM.backtrace(0)[0].method
116
- @processor.ignore_methods[meth] = 'next'
117
- @processor.ignore_methods[method(:debugger)] = 'step'
118
-
119
- @loaded_hook = proc { |file|
120
- check_deferred_breakpoints
121
- }
122
-
123
- @added_hook = proc { |mod, name, exec|
124
- check_deferred_breakpoints
125
- }
126
-
127
- # Use a few Rubinius-specific hooks to trigger checking
128
- # for deferred breakpoints.
129
-
130
- Rubinius::CodeLoader.loaded_hook.add @loaded_hook
131
- Rubinius.add_method_hook.add @added_hook
132
-
133
- end
134
-
135
- # Run user debugger command startup files.
136
- add_startup_files unless @settings[:nx]
137
- add_command_file(@settings[:restore_profile]) if
138
- @settings[:restore_profile] && File.readable?(@settings[:restore_profile])
139
- end
140
-
141
- ## HACK to skip over loader code. Until I find something better...
142
- def skip_loader
143
- cmds =
144
- if @settings[:skip_loader] == :Xdebug
145
- ['continue Rubinius::CodeLoader#load_script',
146
- 'continue 67',
147
- # 'set kernelstep off', # eventually would like 'on'
148
- 'step', 'set hidelevel -1'
149
- ]
150
- else
151
- ['next', 'next',
152
- # 'set kernelstep off', # eventually would like 'on'
153
- 'set hidelevel -1',
154
- 'step', ]
155
- end
156
-
157
- input = Trepan::StringArrayInput.open(cmds)
158
- startup = Trepan::ScriptInterface.new('startup',
159
- Trepan::OutputNull.new(nil),
160
- :input => input)
161
- @intf << startup
162
- end
163
-
164
-
165
- attr_reader :variables, :current_frame, :breakpoints
166
- attr_reader :vm_locations, :history_io, :debugee_thread
167
-
168
- def self.global(settings={})
169
- @global ||= new(settings)
170
- end
171
-
172
- def self.start(settings={})
173
- settings = {:immediate => false, :offset => 1}.merge(settings)
174
- global(settings).start(settings)
175
- end
176
-
177
- # This is simplest API point. This starts up the debugger in the caller
178
- # of this method to begin debugging.
179
- #
180
- def self.here(settings={})
181
- global(settings).start(:offset => 1)
182
- end
183
-
184
- # Startup the debugger, skipping back +offset+ frames. This lets you start
185
- # the debugger straight into callers method.
186
- #
187
- def start(settings = {:immediate => false})
188
- @settings = @settings.merge(settings)
189
- skip_loader if @settings[:skip_loader]
190
- spinup_thread
191
- @debugee_thread = @thread
192
- if @settings[:hide_level]
193
- @processor.hidelevels[@thread] = @settings[:hide_level]
194
- end
195
-
196
- process_cmdfile_setting(settings)
197
-
198
- # Feed info to the debugger thread!
199
- locs = Rubinius::VM.backtrace(@settings[:offset] + 1, true)
200
-
201
- method = Rubinius::CompiledMethod.of_sender
202
-
203
- event = settings[:immediate] ? 'debugger-call' : 'start'
204
- bp = Breakpoint.new('<start>', method, 0, 0, 0, {:event => event} )
205
- channel = Rubinius::Channel.new
206
-
207
- @local_channel.send Rubinius::Tuple[bp, Thread.current, channel, locs]
208
-
209
- # wait for the debugger to release us
210
- channel.receive
211
-
212
- Thread.current.set_debugger_thread @thread
213
- self
214
- end
215
- # ruby-debug compatibility
216
- alias debugger start
217
-
218
- def stop(settings = {})
219
- # Nothing for now...
220
- end
221
-
222
- def add_command_file(cmdfile, opts={}, stderr=$stderr)
223
- unless File.readable?(cmdfile)
224
- if File.exists?(cmdfile)
225
- stderr.puts "Command file '#{cmdfile}' is not readable."
226
- return
227
- else
228
- stderr.puts "Command file '#{cmdfile}' does not exist."
229
- return
230
- end
231
- end
232
- @intf << Trepan::ScriptInterface.new(cmdfile, @output, opts)
233
- end
234
-
235
- def add_startup_files()
236
- seen = {}
237
- cwd_initfile = File.join('.', Trepan::CMD_INITFILE_BASE)
238
- [cwd_initfile, Trepan::CMD_INITFILE].each do |initfile|
239
- full_initfile_path = File.expand_path(initfile)
240
- next if seen[full_initfile_path]
241
- add_command_file(full_initfile_path) if File.readable?(full_initfile_path)
242
- seen[full_initfile_path] = true
243
- end
244
- end
245
-
246
- def process_cmdfile_setting(settings)
247
- settings[:cmdfiles].each do |item|
248
- cmdfile, opts =
249
- if item.kind_of?(Array)
250
- item
251
- else
252
- [item, {}]
253
- end
254
- add_command_file(cmdfile, opts)
255
- end if settings.member?(:cmdfiles)
256
- end
257
-
258
- # Stop and wait for a debuggee thread to send us info about
259
- # stopping at a breakpoint.
260
- #
261
- def listen(step_into=false)
262
- @breakpoint = nil
263
- while true
264
- if @channel
265
- if step_into
266
- @channel << :step
267
- else
268
- @channel << true
269
- end
270
- end
271
-
272
- # Wait for someone to stop
273
- @breakpoint, @debugee_thread, @channel, @vm_locations =
274
- @local_channel.receive
275
-
276
- # Uncache all frames since we stopped at a new place
277
- @frames = []
278
-
279
- set_frame(0)
280
-
281
- if @breakpoint
282
- # Some breakpoints are frame specific. Check for this. hit!
283
- # also removes the breakpoint if it was temporary and hit.
284
- break if @breakpoint.hit!(@vm_locations.first.variables)
285
- else
286
- @processor.step_bp.remove! if @processor.step_bp
287
- break
288
- end
289
- end
290
-
291
- event =
292
- if @breakpoint
293
- @breakpoint.event || 'brkpt'
294
- else
295
- # Evan assures me that the only way the breakpoint can be nil
296
- # is if we are stepping and enter a function.
297
- 'step-call'
298
- end
299
- @processor.instance_variable_set('@event', event)
300
-
301
- if @variables[:show_bytecode]
302
- decode_one
303
- end
304
-
305
- end
306
-
307
- def frame(num)
308
- @frames[num] ||= Frame.new(self, num, @vm_locations[num])
309
- end
310
-
311
- def set_frame(num)
312
- @current_frame = frame(num)
313
- end
314
-
315
- def each_frame(start=0)
316
- start = start.number if start.kind_of?(Frame)
317
-
318
- start.upto(@vm_locations.size-1) do |idx|
319
- yield frame(idx)
320
- end
321
- end
322
-
323
- def add_deferred_breakpoint(klass_name, which, name, line)
324
- dbp = Trepanning::DeferredBreakpoint.new(self, @current_frame, klass_name, which, name,
325
- line, @deferred_breakpoints)
326
- @deferred_breakpoints << dbp
327
- # @processor.brkpts << dbp
328
- end
329
-
330
- def check_deferred_breakpoints
331
- @deferred_breakpoints.delete_if do |bp|
332
- bp.resolve!
333
- end
334
- end
335
-
336
- def send_between(exec, start, fin)
337
- ss = Rubinius::InstructionSet.opcodes_map[:send_stack]
338
- sm = Rubinius::InstructionSet.opcodes_map[:send_method]
339
- sb = Rubinius::InstructionSet.opcodes_map[:send_stack_with_block]
340
-
341
- iseq = exec.iseq
342
-
343
- fin = iseq.size if fin < 0
344
-
345
- i = start
346
- while i < fin
347
- op = iseq[i]
348
- case op
349
- when ss, sm, sb
350
- return exec.literals[iseq[i + 1]]
351
- else
352
- op = Rubinius::InstructionSet[op]
353
- i += (op.arg_count + 1)
354
- end
355
- end
356
-
357
- return nil
358
- end
359
-
360
- def show_code(line=@current_frame.line)
361
- path = @current_frame.method.active_path
362
- str = @processor.line_at(path, line)
363
- unless str.nil?
364
- # if @variables[:highlight]
365
- # fin = @current_frame.method.first_ip_on_line(line + 1)
366
- # name = send_between(@current_frame.method, @current_frame.ip, fin)
367
-
368
- # if name
369
- # str = str.gsub name.to_s, "\033[0;4m#{name}\033[0m"
370
- # end
371
- # end
372
- # info "#{line}: #{str}"
373
- else
374
- show_bytecode(line)
375
- end
376
- end
377
-
378
- def decode_one
379
- ip = @current_frame.next_ip
380
-
381
- meth = @current_frame.method
382
- decoder = Rubinius::InstructionDecoder.new(meth.iseq)
383
- partial = decoder.decode_between(ip, ip+1)
384
-
385
- partial.each do |ins|
386
- op = ins.shift
387
-
388
- ins.each_index do |i|
389
- case op.args[i]
390
- when :literal
391
- ins[i] = meth.literals[ins[i]].inspect
392
- when :local
393
- if meth.local_names
394
- ins[i] = meth.local_names[ins[i]]
395
- end
396
- end
397
- end
398
-
399
- puts "=> ip #{ip} = #{op.opcode} #{ins.join(', ')}"
400
- end
401
- end
402
-
403
- def spinup_thread
404
- return if @thread
405
-
406
- @local_channel = Rubinius::Channel.new
407
-
408
- @thread = Thread.new do
409
- begin
410
- listen
411
- rescue Exception => e
412
- e.render("Listening")
413
- break
414
- end
415
-
416
- @processor.process_commands
417
-
418
- end
419
-
420
- @thread.setup_control!(@local_channel)
421
- end
422
-
423
- private :spinup_thread
424
-
425
- end
426
-
427
- module Kernel
428
- # A simpler way of calling Trepan.start
429
- def debugger(settings = {})
430
- settings = {:immediate => false, :offset => 2}.merge(settings)
431
- Trepan.start(settings)
432
- end
433
- alias breakpoint debugger unless respond_to?(:breakpoint)
434
- end
435
-
436
- if __FILE__ == $0
437
- if ARGV.size > 0
438
- debugger
439
- x = 1
440
- end
441
- end