rbx-trepanning 0.1.0-universal-rubinius-1.2 → 0.2.1-universal-rubinius-1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +3 -0
  3. data/.travis.yml +4 -0
  4. data/ChangeLog +162 -0
  5. data/Gemfile +16 -0
  6. data/NEWS +15 -8
  7. data/README.md +72 -0
  8. data/Rakefile +16 -13
  9. data/app/client.rb +15 -4
  10. data/app/cmd_parse.kpeg +38 -40
  11. data/app/cmd_parse.rb +25 -20
  12. data/app/cmd_parser.rb +1030 -1036
  13. data/app/complete.rb +12 -12
  14. data/app/default.rb +6 -5
  15. data/app/display.rb +2 -2
  16. data/app/frame.rb +17 -4
  17. data/app/method.rb +11 -10
  18. data/app/options.rb +21 -22
  19. data/app/util.rb +17 -10
  20. data/interface/user.rb +2 -2
  21. data/io/input.rb +13 -3
  22. data/lib/trepanning.rb +22 -23
  23. data/processor.rb +32 -32
  24. data/processor/command.rb +32 -13
  25. data/processor/command/backtrace.rb +2 -16
  26. data/processor/command/base/submgr.rb +22 -14
  27. data/processor/command/base/subsubcmd.rb +11 -13
  28. data/processor/command/base/subsubmgr.rb +38 -19
  29. data/processor/command/disassemble.rb +11 -11
  30. data/processor/command/help.rb +24 -24
  31. data/processor/command/shell.rb +17 -17
  32. data/processor/default.rb +5 -2
  33. data/processor/frame.rb +37 -0
  34. data/processor/help.rb +9 -11
  35. data/processor/load_cmds.rb +53 -40
  36. data/processor/location.rb +2 -2
  37. data/processor/mock.rb +8 -9
  38. data/processor/subcmd.rb +12 -12
  39. data/rbx-trepanning.gemspec +4 -3
  40. data/sample/rocky-trepanx-colors.rb +1 -1
  41. data/test/example/factorial.rb +10 -0
  42. data/test/functional/fn_helper.rb +8 -7
  43. data/test/functional/test-break.rb +39 -5
  44. data/test/functional/test-recursive-bt.rb +105 -0
  45. data/test/integration/helper.rb +14 -14
  46. data/test/integration/test-quit.rb +8 -2
  47. data/test/unit/cmd-helper.rb +2 -2
  48. data/test/unit/test-base-subcmd.rb +14 -3
  49. data/test/unit/test-completion.rb +7 -3
  50. data/test/unit/test-io-tcpserver.rb +10 -5
  51. data/test/unit/test-proc-validate.rb +4 -4
  52. metadata +208 -113
  53. data/README.textile +0 -34
data/lib/trepanning.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # -*- coding: utf-8 -*-
3
- # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ # Copyright (C) 2010-2011, 2013 Rocky Bernstein <rockyb@rubyforge.net>
4
4
  require 'readline'
5
5
  require 'compiler/iseq'
6
6
 
@@ -17,7 +17,7 @@ require_relative '../interface/script' # --command interface (includes I/O)
17
17
  require_relative '../interface/client' # client interface (remote debugging)
18
18
  require_relative '../interface/server' # server interface (remote debugging)
19
19
  require_relative '../io/null_output'
20
-
20
+
21
21
  #
22
22
  # The Rubinius Trepan debugger.
23
23
  #
@@ -57,8 +57,8 @@ class Trepan
57
57
  @completion_proc = method(:completion_method)
58
58
 
59
59
  @in_deferred_checking = false
60
-
61
- @intf =
60
+
61
+ @intf =
62
62
  if @settings[:server]
63
63
  @completion_proc = nil
64
64
  opts = Trepan::ServerInterface::DEFAULT_INIT_CONNECTION_OPTS.dup
@@ -110,17 +110,17 @@ class Trepan
110
110
  @loaded_hook = proc { |file|
111
111
  check_deferred_breakpoints
112
112
  }
113
-
113
+
114
114
  @added_hook = proc { |mod, name, exec|
115
115
  check_deferred_breakpoints
116
116
  }
117
117
 
118
118
  # Use a few Rubinius-specific hooks to trigger checking
119
119
  # for deferred breakpoints.
120
-
120
+
121
121
  Rubinius::CodeLoader.loaded_hook.add @loaded_hook
122
122
  Rubinius.add_method_hook.add @added_hook
123
-
123
+
124
124
  end
125
125
 
126
126
  # Run user debugger command startup files.
@@ -131,10 +131,10 @@ class Trepan
131
131
  # such as called from GNU Readline with <TAB>.
132
132
  def completion_method(last_token, leading=Readline.line_buffer)
133
133
  completion = @processor.complete(leading, last_token)
134
- if 1 == completion.size
134
+ if 1 == completion.size
135
135
  completion_token = completion[0]
136
136
  if last_token.end_with?(' ')
137
- if last_token.rstrip == completion_token
137
+ if last_token.rstrip == completion_token
138
138
  # There is nothing more to complete
139
139
  []
140
140
  else
@@ -152,22 +152,21 @@ class Trepan
152
152
 
153
153
  ## HACK to skip over loader code. Until I find something better...
154
154
  def skip_loader
155
- cmds =
155
+ cmds =
156
156
  if @settings[:skip_loader] == :Xdebug
157
157
  ['continue Rubinius::CodeLoader.load_script',
158
- 'continue 67',
158
+ 'next 6',
159
159
  # 'set kernelstep off', # eventually would like 'on'
160
- 'step', 'set hidelevel -1'
160
+ 'step',
161
161
  ]
162
162
  else
163
163
  ['next', 'next', 'next',
164
164
  # 'set kernelstep off', # eventually would like 'on'
165
- 'set hidelevel -1',
166
165
  'step', ]
167
166
  end
168
167
 
169
168
  input = Trepan::StringArrayInput.open(cmds)
170
- startup = Trepan::ScriptInterface.new('startup',
169
+ startup = Trepan::ScriptInterface.new('startup',
171
170
  Trepan::OutputNull.new(nil),
172
171
  :input => input)
173
172
  @intf << startup
@@ -207,7 +206,7 @@ class Trepan
207
206
 
208
207
  process_cmdfile_setting(settings)
209
208
 
210
- # Feed info (breakpoint, debugged program thread, channel and backtrace
209
+ # Feed info (breakpoint, debugged program thread, channel and backtrace
211
210
  # info) to the debugger thread
212
211
  locs = Rubinius::VM.backtrace(@settings[:offset] + 1, true)
213
212
 
@@ -222,7 +221,7 @@ class Trepan
222
221
  # wait for the debugger to release us
223
222
  channel.receive
224
223
 
225
- # Now that there is a debugger on the other end, set the debugged
224
+ # Now that there is a debugger on the other end, set the debugged
226
225
  # program thread to call us when it hits a breakpoint.
227
226
  Thread.current.set_debugger_thread @thread
228
227
  self
@@ -260,7 +259,7 @@ class Trepan
260
259
 
261
260
  def process_cmdfile_setting(settings)
262
261
  settings[:cmdfiles].each do |item|
263
- cmdfile, opts =
262
+ cmdfile, opts =
264
263
  if item.kind_of?(Array)
265
264
  item
266
265
  else
@@ -285,7 +284,7 @@ class Trepan
285
284
  end
286
285
 
287
286
  # Wait for someone to stop
288
- @breakpoint, @debugee_thread, @channel, @vm_locations =
287
+ @breakpoint, @debugee_thread, @channel, @vm_locations =
289
288
  @local_channel.receive
290
289
 
291
290
  # Uncache all frames since we stopped at a new place
@@ -299,7 +298,7 @@ class Trepan
299
298
  status = @breakpoint.hit!(@vm_locations.first.variables)
300
299
  if status
301
300
  break
302
- elsif @breakpoint.enabled? && status.nil?
301
+ elsif @breakpoint.enabled? && status.nil?
303
302
  # A permanent breakpoint. Check the condition.
304
303
  break if @breakpoint.condition?(@current_frame.binding)
305
304
  end
@@ -309,7 +308,7 @@ class Trepan
309
308
  end
310
309
  end
311
310
 
312
- event =
311
+ event =
313
312
  if @breakpoint
314
313
  @breakpoint.event || 'brkpt'
315
314
  else
@@ -342,15 +341,15 @@ class Trepan
342
341
  end
343
342
 
344
343
  def add_deferred_breakpoint(klass_name, which, name, line)
345
- dbp = Trepan::DeferredBreakpoint.new(self, @current_frame, klass_name,
346
- which, name, line,
344
+ dbp = Trepan::DeferredBreakpoint.new(self, @current_frame, klass_name,
345
+ which, name, line,
347
346
  @deferred_breakpoints)
348
347
  @deferred_breakpoints << dbp
349
348
  # @processor.brkpts << dbp
350
349
  end
351
350
 
352
351
  def check_deferred_breakpoints
353
- unless @in_deferred_checking
352
+ unless @in_deferred_checking
354
353
  @in_deferred_checking = true
355
354
  @deferred_breakpoints.delete_if do |bp|
356
355
  bp.resolve!
data/processor.rb CHANGED
@@ -1,13 +1,13 @@
1
1
  # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
- # The main "driver" class for a command processor. Other parts of the
2
+ # The main "driver" class for a command processor. Other parts of the
3
3
  # command class and debugger command objects are pulled in from here.
4
4
 
5
5
  require 'set'
6
6
 
7
7
  require 'rubygems'; require 'require_relative'
8
- ## %w(default display eventbuf eval load_cmds location frame hook msg
8
+ ## %w(default display eventbuf eval load_cmds location frame hook msg
9
9
  ## validate).each do
10
- %w(default breakpoint disassemble display eval eventbuf load_cmds location
10
+ %w(default breakpoint disassemble display eval eventbuf load_cmds location
11
11
  frame hook msg running stepping validate).each do
12
12
  |mod_str|
13
13
  require_relative "processor/#{mod_str}"
@@ -31,7 +31,7 @@ class Trepan
31
31
  ## FIXME 1.9.2 has attr_reader !
32
32
  attr_accessor :debug_nest # Number of nested debugs. Used in showing
33
33
  # prompt.
34
- attr_accessor :different_pos # Same type as settings[:different]
34
+ attr_accessor :different_pos # Same type as settings[:different]
35
35
  # this is the temporary value for the
36
36
  # next stop while settings is the default
37
37
  # value to use.
@@ -39,8 +39,8 @@ class Trepan
39
39
  attr_reader :intf # Current interface
40
40
  # Trepan::Core instance)
41
41
  attr_accessor :leave_cmd_loop # Commands set this to signal to leave
42
- # the command loop (which often continues to
43
- # run the debugged program).
42
+ # the command loop (which often continues to
43
+ # run the debugged program).
44
44
  attr_accessor :line_no # Last line shown in "list" command
45
45
  attr_accessor :next_level # Fixnum. frame.stack_size has to
46
46
  # be <= than this. If next'ing,
@@ -48,7 +48,7 @@ class Trepan
48
48
  attr_accessor :next_thread # Thread. If non-nil then in
49
49
  # stepping the thread has to be
50
50
  # this thread.
51
- attr_accessor :pass_exception # Pass an exception back
51
+ attr_accessor :pass_exception # Pass an exception back
52
52
  attr_accessor :prompt # String print before requesting input
53
53
  attr_reader :settings # Hash[:symbol] of command
54
54
  # processor settings
@@ -57,7 +57,7 @@ class Trepan
57
57
  # The following are used in to force stopping at a different line
58
58
  # number. FIXME: could generalize to a position object.
59
59
  attr_accessor :last_pos # Last position. 6-Tuple: of
60
- # [location, container, stack_size,
60
+ # [location, container, stack_size,
61
61
  # current_thread, pc_offset]
62
62
 
63
63
 
@@ -71,7 +71,7 @@ class Trepan
71
71
  @next_level = 32000
72
72
  @next_thread = nil
73
73
  @user_variables = 0
74
-
74
+
75
75
 
76
76
  start_cmds = settings.delete(:start_cmds)
77
77
  start_file = settings.delete(:start_file)
@@ -81,18 +81,18 @@ class Trepan
81
81
 
82
82
  # FIXME: Rework using a general "set substitute file" command and
83
83
  # a global default profile which gets read.
84
- prelude_file = File.expand_path(File.join(File.dirname(__FILE__),
84
+ prelude_file = File.expand_path(File.join(File.dirname(__FILE__),
85
85
  %w(.. data prelude.rb)))
86
86
 
87
87
  # Start with empty thread and frame info.
88
- frame_teardown
88
+ frame_teardown
89
89
 
90
90
  # Run initialization routines for each of the "submodule"s.
91
91
  # load_cmds has to come first.
92
92
  ## %w(load_cmds breakpoint display eventbuf frame running validate
93
93
  ## ).each do |submod|
94
- %w(load_cmds breakpoint display eventbuf frame running
95
- stepping validate).each do
94
+ %w(load_cmds breakpoint display eventbuf frame running
95
+ stepping validate).each do
96
96
  |submod|
97
97
  self.send("#{submod}_initialize")
98
98
  end
@@ -115,7 +115,7 @@ class Trepan
115
115
  end
116
116
 
117
117
  def compute_prompt
118
- "(#{@settings[:prompt]}): "
118
+ "(#{@settings[:prompt]}): "
119
119
  end
120
120
 
121
121
  # Check that we meed the criteria that cmd specifies it needs
@@ -124,13 +124,13 @@ class Trepan
124
124
  # Check we have frame is not null
125
125
  min_args = cmd.class.const_get(:MIN_ARGS)
126
126
  if nargs < min_args
127
- errmsg(("Command '%s' needs at least %d argument(s); " +
127
+ errmsg(("Command '%s' needs at least %d argument(s); " +
128
128
  "got %d.") % [name, min_args, nargs])
129
129
  return false
130
130
  end
131
131
  max_args = cmd.class.const_get(:MAX_ARGS)
132
132
  if max_args and nargs > max_args
133
- errmsg(("Command '%s' needs at most %d argument(s); " +
133
+ errmsg(("Command '%s' needs at most %d argument(s); " +
134
134
  "got %d.") % [name, max_args, nargs])
135
135
  return false
136
136
  end
@@ -154,14 +154,14 @@ class Trepan
154
154
  return true if @intf.input_eof? && intf_size == 1
155
155
  while intf_size > 1 || !@intf.input_eof?
156
156
  begin
157
- @current_command =
157
+ @current_command =
158
158
  if @cmd_queue.empty?
159
159
  # Leave trailing blanks on for the "complete" command
160
- read_command.chomp
160
+ read_command.chomp
161
161
  else
162
162
  @cmd_queue.shift
163
163
  end
164
- if @current_command.empty?
164
+ if @current_command.empty?
165
165
  next unless @last_command && intf.interactive?;
166
166
  end
167
167
  next if @current_command[0..0] == '#' # Skip comment lines
@@ -200,7 +200,7 @@ class Trepan
200
200
  @unconditional_prehooks.run
201
201
  if breakpoint?
202
202
  delete_breakpoint(@brkpt) if @brkpt.temp?
203
- @last_pos = [@frame.vm_location, @stack_size, @current_thread, @event]
203
+ @last_pos = [@frame.vm_location, @stack_size, @current_thread, @event]
204
204
  end
205
205
 
206
206
  if stepping_skip? # || @stack_size <= @hide_level
@@ -219,12 +219,12 @@ class Trepan
219
219
 
220
220
  @leave_cmd_loop = false
221
221
  print_location unless @settings[:traceprint]
222
- # if 'trace-var' == @event
222
+ # if 'trace-var' == @event
223
223
  # msg "Note: we are stopped *after* the above location."
224
224
  # end
225
225
 
226
226
  @eventbuf.add_mark if @settings[:tracebuffer]
227
-
227
+
228
228
  @return_to_program = false
229
229
  @cmdloop_prehooks.run
230
230
  return false
@@ -239,7 +239,7 @@ class Trepan
239
239
  # if settings[:traceprint]
240
240
  # @return_to_program = 'step'
241
241
  # else
242
- if !skip_command
242
+ if !skip_command
243
243
  break if process_command_and_quit?()
244
244
  end
245
245
  # end
@@ -274,7 +274,7 @@ class Trepan
274
274
  # Run current_command, a String. @last_command is set after the
275
275
  # command is run if it is a command.
276
276
  def run_command(current_command)
277
- eval_command =
277
+ eval_command =
278
278
  if current_command[0..0] == '!'
279
279
  current_command[0] = ''
280
280
  else
@@ -295,7 +295,7 @@ class Trepan
295
295
  break unless @macros.member?(macro_cmd_name)
296
296
  current_command = @macros[macro_cmd_name][0].call(*args[1..-1])
297
297
  msg current_command.inspect if settings[:debugmacro]
298
- if current_command.is_a?(Array) &&
298
+ if current_command.is_a?(Array) &&
299
299
  current_command.all? {|val| val.is_a?(String)}
300
300
  args = (first=current_command.shift).split
301
301
  @cmd_queue += current_command
@@ -310,21 +310,21 @@ class Trepan
310
310
  end
311
311
 
312
312
  @cmd_name = args[0]
313
- run_cmd_name =
313
+ run_cmd_name =
314
314
  if @aliases.member?(@cmd_name)
315
- @aliases[@cmd_name]
315
+ @aliases[@cmd_name]
316
316
  else
317
317
  @cmd_name
318
318
  end
319
-
319
+
320
320
  run_cmd_name = uniq_abbrev(@commands.keys, run_cmd_name) if
321
321
  !@commands.member?(run_cmd_name) && @settings[:abbrev]
322
-
322
+
323
323
  if @commands.member?(run_cmd_name)
324
324
  cmd = @commands[run_cmd_name]
325
325
  if ok_for_running(cmd, run_cmd_name, args.size-1)
326
326
  @cmd_argstr = current_command[@cmd_name.size..-1].lstrip
327
- cmd.run(args)
327
+ cmd.run(args)
328
328
  @last_command = current_command
329
329
  end
330
330
  return false
@@ -346,7 +346,7 @@ class Trepan
346
346
 
347
347
  # Error message when a command doesn't exist
348
348
  def undefined_command(cmd_name)
349
- begin
349
+ begin
350
350
  errmsg('Undefined command: "%s". Try "help".' % cmd_name)
351
351
  rescue
352
352
  $stderr.puts 'Undefined command: "%s". Try "help".' % cmd_name
@@ -398,7 +398,7 @@ if __FILE__ == $0
398
398
  # end
399
399
  # $input = ['1+2']
400
400
  # cmdproc.process_command_and_quit?
401
- # $input = ['!s = 5'] # ! means eval line
401
+ # $input = ['!s = 5'] # ! means eval line
402
402
  # cmdproc.process_command_and_quit?
403
403
  # end
404
404
  end
data/processor/command.rb CHANGED
@@ -1,9 +1,10 @@
1
1
  # -*- coding: utf-8 -*-
2
- # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
+ # Copyright (C) 2010-2011, 2013 Rocky Bernstein <rockyb@rubyforge.net>
3
3
  # Base class of all commands. Code common to all commands is here.
4
4
  # Note: don't end classname with Command (capital C) since main
5
- # will think this a command name like QuitCommand
5
+ # will think this a command name like QuitCommand
6
6
  require 'rubygems'; require 'require_relative'
7
+ require 'redcard/rubinius'
7
8
  require 'columnize'
8
9
  require_relative '../app/complete'
9
10
 
@@ -31,7 +32,7 @@ class Trepan
31
32
  # List commands arranged in an aligned columns
32
33
  def columnize_commands(commands)
33
34
  width = settings[:maxwidth]
34
- Columnize::columnize(commands, width, ' ' * 4,
35
+ Columnize::columnize(commands, width, ' ' * 4,
35
36
  true, true, ' ' * 2).chomp
36
37
  end
37
38
 
@@ -53,7 +54,7 @@ class Trepan
53
54
  end
54
55
 
55
56
  def obj_const(obj, name)
56
- obj.class.const_get(name)
57
+ obj.class.const_get(name)
57
58
  end
58
59
 
59
60
  def msg(message, opts={})
@@ -65,15 +66,33 @@ class Trepan
65
66
  @proc.msg_nocr(msg, opts)
66
67
  end
67
68
 
69
+ def get_const(klass, name)
70
+ name = name.to_sym if RedCard.check '1.9'
71
+ if klass.constants.member?(name)
72
+ klass.const_get(name)
73
+ else
74
+ nil
75
+ end
76
+ end
77
+
78
+ def set_const(klass, name, val)
79
+ name = name.to_sym if RedCard.check '1.9'
80
+ if klass.constants.member?(name)
81
+ klass.const_set(name, val)
82
+ else
83
+ nil
84
+ end
85
+ end
86
+
68
87
  def my_const(name)
69
88
  # Set class constant SHORT_HELP to be the first line of HELP
70
89
  # unless it has been defined in the class already.
71
90
  # The below was the simplest way I could find to do this since
72
91
  # we are the super class but want to set the subclass's constant.
73
92
  # defined? didn't seem to work here.
74
- c = self.class.constants
75
- if c.member?('HELP') and !c.member?('SHORT_HELP')
76
- short_help = self.class.const_get(:HELP).split("\n")[0].chomp('.')
93
+ short_help = get_const(self.class, 'SHORT_HELP')
94
+ if !short_help and (help = get_const(self.class, 'HELP'))
95
+ short_help = help
77
96
  self.class.const_set(:SHORT_HELP, short_help)
78
97
  end
79
98
  self.class.const_get(name)
@@ -97,18 +116,18 @@ class Trepan
97
116
  end
98
117
 
99
118
  def short_help
100
- help_constant_sym = if self.class.constants.member?('SHORT_HELP')
101
- :SHORT_HELP
119
+ help_constant_sym = if self.class.constants.member?('SHORT_HELP')
120
+ :SHORT_HELP
102
121
  else :HELP
103
122
  end
104
123
  my_const(help_constant_sym)
105
124
  end
106
125
 
107
126
  # Define a method called 'complete' on the singleton class.
108
- def self.completion(ary)
109
- self.send(:define_method,
110
- :complete,
111
- Proc.new {|prefix|
127
+ def self.completion(ary)
128
+ self.send(:define_method,
129
+ :complete,
130
+ Proc.new {|prefix|
112
131
  Trepan::Complete.complete_token(ary, prefix) })
113
132
  end
114
133