rb8-trepanning 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/CHANGES +18 -4
  2. data/ChangeLog +100 -87
  3. data/Makefile +23 -4
  4. data/README.textile +3 -3
  5. data/Rakefile +26 -20
  6. data/app/complete.rb +13 -13
  7. data/app/default.rb +8 -8
  8. data/app/display.rb +7 -7
  9. data/app/frame.rb +8 -8
  10. data/app/irb.rb +15 -15
  11. data/app/options.rb +25 -25
  12. data/app/run.rb +16 -8
  13. data/app/util.rb +7 -7
  14. data/bin/trepan8 +2 -2
  15. data/check-filter.rb +21 -0
  16. data/interface.rb +4 -4
  17. data/interface/user.rb +11 -11
  18. data/io.rb +18 -19
  19. data/io/input.rb +14 -12
  20. data/lib/debugger.rb +3 -1
  21. data/lib/trepanning.rb +30 -28
  22. data/processor.rb +41 -38
  23. data/processor/command.rb +9 -9
  24. data/processor/command/alias.rb +6 -6
  25. data/processor/command/down.rb +1 -2
  26. data/processor/command/edit.rb +12 -8
  27. data/processor/command/eval.rb +7 -7
  28. data/processor/command/info_subcmd/macro.rb +6 -6
  29. data/processor/command/info_subcmd/program.rb +5 -1
  30. data/processor/command/macro.rb +6 -6
  31. data/processor/command/show_subcmd/abbrev.rb +2 -2
  32. data/processor/command/up.rb +1 -2
  33. data/processor/complete.rb +120 -0
  34. data/processor/default.rb +13 -9
  35. data/processor/load_cmds.rb +18 -97
  36. data/processor/location.rb +34 -31
  37. data/processor/msg.rb +5 -5
  38. data/processor/validate.rb +44 -35
  39. data/test/data/break_loop_bug.right +2 -2
  40. data/test/data/edit.cmd +1 -1
  41. data/test/data/edit.right +7 -1
  42. data/test/data/printvar.right +2 -2
  43. data/test/data/raise.right +0 -1
  44. data/test/data/trace-mingw.right +28 -0
  45. data/test/integration/.gitignore +1 -0
  46. data/test/integration/test-raise.rb +10 -1
  47. data/test/integration/test-trace.rb +10 -6
  48. data/test/unit/test-app-options.rb +9 -3
  49. data/test/unit/test-app-run.rb +8 -1
  50. data/test/unit/test-cmd-alias.rb +2 -2
  51. data/test/unit/test-proc-default.rb +34 -0
  52. metadata +10 -6
@@ -1,4 +1,6 @@
1
- # Module/Package to do the most-common thing: get into the debugger with
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ # Module/Package to do the most-common thing: get into the debugger with
2
4
  # minimal fuss. Compare with: require "debug"
3
5
  require 'rubygems'
4
6
  require 'require_relative'
@@ -1,3 +1,5 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2013 Rocky Bernstein <rockyb@rubyforge.net>
1
3
  require 'rubygems'
2
4
  require 'pp'
3
5
  require 'stringio'
@@ -18,10 +20,10 @@ module Trepan
18
20
  # The method is called when we want to do debugger command completion
19
21
  # such as called from GNU Readline with <TAB>.
20
22
  def self.completion_method(last_token, leading=nil)
21
- if leading.nil?
23
+ if leading.nil?
22
24
  if Readline.respond_to?(:line_buffer)
23
- completion =
24
- Trepan.handler.cmdproc.complete(Readline.line_buffer,
25
+ completion =
26
+ Trepan.handler.cmdproc.complete(Readline.line_buffer,
25
27
  last_token)
26
28
  else
27
29
  completion = Trepan.handler.cmdproc.complete(last_token, '')
@@ -29,10 +31,10 @@ module Trepan
29
31
  else
30
32
  completion = Trepan.handler.cmdproc.complete(leading, last_token)
31
33
  end
32
- if 1 == completion.size
34
+ if 1 == completion.size
33
35
  completion_token = completion[0]
34
36
  if last_token.end_with?(' ')
35
- if last_token.rstrip == completion_token
37
+ if last_token.rstrip == completion_token
36
38
  # There is nothing more to complete
37
39
  []
38
40
  else
@@ -65,14 +67,14 @@ module Trepan
65
67
  # gdb-style annotation mode. Used in GNU Emacs interface
66
68
  attr_accessor :annotate
67
69
 
68
- # in remote mode, wait for the remote connection
70
+ # in remote mode, wait for the remote connection
69
71
  attr_accessor :wait_connection
70
72
 
71
73
  # If start_sentinal is set, it is a string to look for in caller()
72
74
  # and is used to see if the call stack is truncated. Is also
73
75
  # defined in app/default.rb
74
- attr_accessor :start_sentinal
75
-
76
+ attr_accessor :start_sentinal
77
+
76
78
  attr_reader :thread, :control_thread, :cmd_port, :ctrl_port
77
79
 
78
80
  def interface=(value) # :nodoc:
@@ -101,37 +103,37 @@ module Trepan
101
103
  # <i>Note that if you want to stop debugger, you must call
102
104
  # Trepan.stop as many time as you called Trepan.start
103
105
  # method.</i>
104
- #
106
+ #
105
107
  # +options+ is a hash used to set various debugging options.
106
108
  # Set :init true if you want to save ARGV and some variables which
107
109
  # make a debugger restart possible. Only the first time :init is set true
108
- # will values get set. Since ARGV is saved, you should make sure
109
- # it hasn't been changed before the (first) call.
110
+ # will values get set. Since ARGV is saved, you should make sure
111
+ # it hasn't been changed before the (first) call.
110
112
  # Set :post_mortem true if you want to enter post-mortem debugging
111
113
  # on an uncaught exception. Once post-mortem debugging is set, it can't
112
114
  # be unset.
113
115
  def start(options={}, &block)
114
116
  options = Trepan::DEFAULT_START_SETTINGS.merge(options)
115
117
  if options[:init]
116
- Trepan.const_set('ARGV', ARGV.clone) unless
118
+ Trepan.const_set('ARGV', ARGV.clone) unless
117
119
  defined? Trepan::ARGV
118
- Trepan.const_set('PROG_SCRIPT', $0) unless
120
+ Trepan.const_set('PROG_SCRIPT', $0) unless
119
121
  defined? Trepan::PROG_SCRIPT
120
- Trepan.const_set('INITIAL_DIR', Dir.pwd) unless
122
+ Trepan.const_set('INITIAL_DIR', Dir.pwd) unless
121
123
  defined? Trepan::INITIAL_DIR
122
124
  end
123
125
  Trepan.tracing = options[:tracing] unless options[:tracing].nil?
124
- retval = Debugger.started? ? block && block.call(self) : Debugger.start_(&block)
126
+ retval = Debugger.started? ? block && block.call(self) : Debugger.start_(&block)
125
127
  if options[:post_mortem]
126
128
  post_mortem
127
129
  end
128
130
  return retval
129
131
  end
130
-
132
+
131
133
  def started?
132
134
  Debugger.started?
133
135
  end
134
-
136
+
135
137
  #
136
138
  # Starts a remote debugger.
137
139
  #
@@ -150,12 +152,12 @@ module Trepan
150
152
  end
151
153
 
152
154
  ctrl_port = start_control(host, ctrl_port)
153
-
155
+
154
156
  yield if block_given?
155
-
157
+
156
158
  mutex = Mutex.new
157
159
  proceed = ConditionVariable.new
158
-
160
+
159
161
  server = TCPServer.new(host, cmd_port)
160
162
  @cmd_port = cmd_port = server.addr[1]
161
163
  @thread = Debugger::DebugThread.new do
@@ -171,11 +173,11 @@ module Trepan
171
173
  if wait_connection
172
174
  mutex.synchronize do
173
175
  proceed.wait(mutex)
174
- end
176
+ end
175
177
  end
176
178
  end
177
179
  alias start_server start_remote
178
-
180
+
179
181
  def start_control(host = nil, ctrl_port = PORT + 1) # :nodoc:
180
182
  raise "Debugger is not started" unless started?
181
183
  return @ctrl_port if defined?(@control_thread) && @control_thread
@@ -190,7 +192,7 @@ module Trepan
190
192
  end
191
193
  @ctrl_port
192
194
  end
193
-
195
+
194
196
  #
195
197
  # Connects to the remote debugger
196
198
  #
@@ -199,10 +201,10 @@ module Trepan
199
201
  interface = Trepan::LocalInterface.new
200
202
  socket = TCPSocket.new(host, port)
201
203
  puts "Connected."
202
-
204
+
203
205
  catch(:exit) do
204
206
  while (line = socket.gets)
205
- case line
207
+ case line
206
208
  when /^PROMPT (.*)$/
207
209
  input = interface.read_command($1)
208
210
  throw :exit unless input
@@ -231,14 +233,14 @@ module Trepan
231
233
  end
232
234
  @@intf << Trepan::ScriptInterface.new(cmdfile, @output, opts)
233
235
  end
234
-
236
+
235
237
  def add_startup_files()
236
238
  seen = {}
237
239
  cwd_initfile = File.join('.', Trepan::CMD_INITFILE_BASE)
238
240
  [cwd_initfile, Trepan::CMD_INITFILE].each do |initfile|
239
241
  full_initfile_path = File.expand_path(initfile)
240
242
  next if seen[full_initfile_path]
241
- add_command_file(full_initfile_path) if
243
+ add_command_file(full_initfile_path) if
242
244
  File.readable?(full_initfile_path)
243
245
  seen[full_initfile_path] = true
244
246
  end
@@ -249,7 +251,7 @@ module Trepan
249
251
  puts caller
250
252
  exit
251
253
  settings[:cmdfiles].each do |item|
252
- cmdfile, opts =
254
+ cmdfile, opts =
253
255
  if item.kind_of?(Array)
254
256
  item
255
257
  else
@@ -1,13 +1,13 @@
1
- # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
- # The main "driver" class for a command processor. Other parts of the
1
+ # Copyright (C) 2010-2012 Rocky Bernstein <rockyb@rubyforge.net>
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
8
  # Other debuggers have in addition: breakpoint disassemble stepping
9
- %w(default display eval eventbuf frame hook load_cmds location msg running
10
- validate).each do
9
+ %w(complete default display eval eventbuf frame hook load_cmds
10
+ location msg running validate).each do
11
11
  |mod_str|
12
12
  require_relative File.join('processor', mod_str);
13
13
  end
@@ -26,7 +26,7 @@ module Trepan
26
26
  ## attr_reader :core # Trepan core object
27
27
  attr_reader :current_command # Current command getting run, a String.
28
28
 
29
- attr_accessor :dbgr # Trepan instance (via
29
+ attr_accessor :dbgr # Trepan instance (via
30
30
  # Trepan::Core instance)
31
31
  ## FIXME 1.9.2 has attr_reader !
32
32
  attr_accessor :interfaces
@@ -34,7 +34,7 @@ module Trepan
34
34
 
35
35
  attr_accessor :debug_nest # Number of nested debugs. Used in showing
36
36
  # prompt.
37
- attr_accessor :different_pos # Same type as settings[:different]
37
+ attr_accessor :different_pos # Same type as settings[:different]
38
38
  # this is the temporary value for the
39
39
  # next stop while settings is the default
40
40
  # value to use.
@@ -43,8 +43,8 @@ module Trepan
43
43
  # Trepan::Core instance)
44
44
  attr_reader :interfaces # Array of all interfaces
45
45
  attr_accessor :leave_cmd_loop # Commands set this to signal to leave
46
- # the command loop (which often continues to
47
- # run the debugged program).
46
+ # the command loop (which often continues to
47
+ # run the debugged program).
48
48
  attr_accessor :line_no # Last line shown in "list" command
49
49
  attr_accessor :next_level # Fixnum. frame.stack_size has to
50
50
  # be <= than this. If next'ing,
@@ -52,7 +52,7 @@ module Trepan
52
52
  attr_accessor :next_thread # Thread. If non-nil then in
53
53
  # stepping the thread has to be
54
54
  # this thread.
55
- attr_accessor :pass_exception # Pass an exception back
55
+ attr_accessor :pass_exception # Pass an exception back
56
56
  attr_accessor :prompt # String print before requesting input
57
57
  attr_reader :settings # Hash[:symbol] of command
58
58
  # processor settings
@@ -61,7 +61,7 @@ module Trepan
61
61
  # The following are used in to force stopping at a different line
62
62
  # number. FIXME: could generalize to a position object.
63
63
  attr_accessor :last_pos # Last position. 6-Tuple: of
64
- # [location, container, stack_size,
64
+ # [location, container, stack_size,
65
65
  # current_thread, pc_offset]
66
66
 
67
67
  ## def initialize(dbgr, settings={})
@@ -78,7 +78,7 @@ module Trepan
78
78
  @next_thread = nil
79
79
  @user_variables = 0
80
80
  @state = nil
81
-
81
+
82
82
 
83
83
  start_cmds = settings.delete(:start_cmds)
84
84
  start_file = settings.delete(:start_file)
@@ -88,24 +88,24 @@ module Trepan
88
88
 
89
89
  # FIXME: Rework using a general "set substitute file" command and
90
90
  # a global default profile which gets read.
91
- prelude_file = File.expand_path(File.join(File.dirname(__FILE__),
91
+ prelude_file = File.expand_path(File.join(File.dirname(__FILE__),
92
92
  %w(.. data prelude.rb)))
93
93
 
94
94
  # Start with empty thread and frame info.
95
- frame_teardown
95
+ frame_teardown
96
96
 
97
97
  # Run initialization routines for each of the "submodule"s.
98
98
  # load_cmds has to come first.
99
99
  ## %w(load_cmds breakpoint display eventbuf frame running validate
100
100
  ## ).each do |submod|
101
- ## %w(load_cmds breakpoint display eventbuf frame running
102
- ## stepping validate).each do
103
- %w(load_cmds display eventbuf frame running validate).each do
101
+ ## %w(load_cmds breakpoint display eventbuf frame running
102
+ ## stepping validate).each do
103
+ %w(load_cmds display eventbuf frame running validate).each do
104
104
  |submod|
105
105
  self.send("#{submod}_initialize")
106
106
  end
107
107
  hook_initialize(commands)
108
- unconditional_prehooks.insert_if_new(-1, *@trace_hook) if
108
+ unconditional_prehooks.insert_if_new(-1, *@trace_hook) if
109
109
  @settings[:traceprint]
110
110
  end
111
111
 
@@ -124,7 +124,7 @@ module Trepan
124
124
  end
125
125
 
126
126
  def compute_prompt
127
- "(#{@settings[:prompt]}): "
127
+ "(#{@settings[:prompt]}): "
128
128
  end
129
129
 
130
130
  # Check that we meed the criteria that cmd specifies it needs
@@ -133,13 +133,13 @@ module Trepan
133
133
  # Check we have frame is not null
134
134
  min_args = cmd.class.const_get(:MIN_ARGS)
135
135
  if nargs < min_args
136
- errmsg(("Command '%s' needs at least %d argument(s); " +
136
+ errmsg(("Command '%s' needs at least %d argument(s); " +
137
137
  "got %d.") % [name, min_args, nargs])
138
138
  return false
139
139
  end
140
140
  max_args = cmd.class.const_get(:MAX_ARGS)
141
141
  if max_args and nargs > max_args
142
- errmsg(("Command '%s' needs at most %d argument(s); " +
142
+ errmsg(("Command '%s' needs at most %d argument(s); " +
143
143
  "got %d.") % [name, max_args, nargs])
144
144
  return false
145
145
  end
@@ -167,14 +167,14 @@ module Trepan
167
167
  return true if @intf.input_eof? && intf_size == 1
168
168
  while intf_size > 1 || !@intf.input_eof?
169
169
  begin
170
- @current_command =
170
+ @current_command =
171
171
  if @cmd_queue.empty?
172
172
  # Leave trailing blanks on for the "complete" command
173
- read_command.chomp
173
+ read_command.chomp
174
174
  else
175
175
  @cmd_queue.shift
176
176
  end
177
- if @current_command.empty?
177
+ if @current_command.empty?
178
178
  next unless @last_command && intf.interactive?;
179
179
  end
180
180
  next if @current_command[0..0] == '#' # Skip comment lines
@@ -218,7 +218,7 @@ module Trepan
218
218
 
219
219
  if breakpoint?
220
220
  delete_breakpoint(@brkpt) if @brkpt.temp?
221
- @last_pos = [@frame.vm_location, @stack_size, @current_thread, @event]
221
+ @last_pos = [@frame.vm_location, @stack_size, @current_thread, @event]
222
222
  end
223
223
 
224
224
  if stepping_skip? # || @stack_size <= @hide_level
@@ -237,12 +237,12 @@ module Trepan
237
237
 
238
238
  @leave_cmd_loop = false
239
239
  print_location
240
- # if 'trace-var' == @event
240
+ # if 'trace-var' == @event
241
241
  # msg "Note: we are stopped *after* the above location."
242
242
  # end
243
243
 
244
244
  @eventbuf.add_mark if @settings[:tracebuffer]
245
-
245
+
246
246
  @return_to_program = false
247
247
  @cmdloop_prehooks.run
248
248
  return false
@@ -254,7 +254,10 @@ module Trepan
254
254
  @context = context
255
255
  @state = state
256
256
  frame_setup(@context, @state)
257
- # @event = @core.event
257
+
258
+ # FIXME: put in a method 'compute_event'
259
+ @event = @context.stop_reason.to_s
260
+ @event = 'line' if @event == 'step'
258
261
 
259
262
  @unconditional_prehooks.run
260
263
  if @settings[:traceprint]
@@ -263,7 +266,7 @@ module Trepan
263
266
  end
264
267
  # if breakpoint?
265
268
  # @last_pos = [@frame.source_container, frame_line,
266
- # @stack_size, @current_thread, @event,
269
+ # @stack_size, @current_thread, @event,
267
270
  # @frame.pc_offset]
268
271
  # else
269
272
  # return if stepping_skip? || @stack_size <= @hide_level
@@ -273,7 +276,7 @@ module Trepan
273
276
 
274
277
  @leave_cmd_loop = false
275
278
  print_location
276
- # if 'trace-var' == @event
279
+ # if 'trace-var' == @event
277
280
  # msg "Note: we are stopped *after* the above location."
278
281
  # end
279
282
 
@@ -302,7 +305,7 @@ module Trepan
302
305
  # Run current_command, a String. @last_command is set after the
303
306
  # command is run if it is a command.
304
307
  def run_command(current_command)
305
- eval_command =
308
+ eval_command =
306
309
  if current_command[0..0] == '!'
307
310
  current_command[0] = ''
308
311
  else
@@ -323,7 +326,7 @@ module Trepan
323
326
  break unless @macros.member?(macro_cmd_name)
324
327
  current_command = @macros[macro_cmd_name][0].call(*args[1..-1])
325
328
  msg current_command.inspect if settings[:debugmacro]
326
- if current_command.is_a?(Array) &&
329
+ if current_command.is_a?(Array) &&
327
330
  current_command.all? {|val| val.is_a?(String)}
328
331
  args = (first=current_command.shift).split
329
332
  @cmd_queue += current_command
@@ -338,21 +341,21 @@ module Trepan
338
341
  end
339
342
 
340
343
  @cmd_name = args[0]
341
- run_cmd_name =
344
+ run_cmd_name =
342
345
  if @aliases.member?(@cmd_name)
343
- @aliases[@cmd_name]
346
+ @aliases[@cmd_name]
344
347
  else
345
348
  @cmd_name
346
349
  end
347
-
350
+
348
351
  run_cmd_name = uniq_abbrev(@commands.keys, run_cmd_name) if
349
352
  !@commands.member?(run_cmd_name) && @settings[:abbrev]
350
-
353
+
351
354
  if @commands.member?(run_cmd_name)
352
355
  cmd = @commands[run_cmd_name]
353
356
  if ok_for_running(cmd, run_cmd_name, args.size-1)
354
357
  @cmd_argstr = current_command[@cmd_name.size..-1].lstrip
355
- cmd.run(args)
358
+ cmd.run(args)
356
359
  @last_command = current_command
357
360
  end
358
361
  return false
@@ -373,7 +376,7 @@ module Trepan
373
376
 
374
377
  # Error message when a command doesn't exist
375
378
  def undefined_command(cmd_name)
376
- begin
379
+ begin
377
380
  errmsg('Undefined command: "%s". Try "help".' % cmd_name)
378
381
  rescue
379
382
  $stderr.puts 'Undefined command: "%s". Try "help".' % cmd_name
@@ -427,7 +430,7 @@ if __FILE__ == $0
427
430
  # end
428
431
  # $input = ['1+2']
429
432
  # cmdproc.process_command_and_quit?
430
- # $input = ['!s = 5'] # ! means eval line
433
+ # $input = ['!s = 5'] # ! means eval line
431
434
  # cmdproc.process_command_and_quit?
432
435
  # end
433
436
  end
@@ -2,7 +2,7 @@
2
2
  # Copyright (C) 2010, 2011 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
7
  require 'columnize'
8
8
  require_relative '../app/complete'
@@ -33,7 +33,7 @@ module Trepan
33
33
  # List commands arranged in an aligned columns
34
34
  def columnize_commands(commands)
35
35
  width = settings[:maxwidth]
36
- Columnize::columnize(commands, width, ' ' * 4,
36
+ Columnize::columnize(commands, width, ' ' * 4,
37
37
  true, true, ' ' * 2).chomp
38
38
  end
39
39
 
@@ -55,7 +55,7 @@ module Trepan
55
55
  end
56
56
 
57
57
  def obj_const(obj, name)
58
- obj.class.const_get(name)
58
+ obj.class.const_get(name)
59
59
  end
60
60
 
61
61
  def msg(message, opts={})
@@ -102,18 +102,18 @@ module Trepan
102
102
  end
103
103
 
104
104
  def short_help
105
- help_constant_sym = if self.class.constants.member?('SHORT_HELP')
106
- :SHORT_HELP
105
+ help_constant_sym = if self.class.constants.member?('SHORT_HELP')
106
+ :SHORT_HELP
107
107
  else :HELP
108
108
  end
109
109
  my_const(help_constant_sym)
110
110
  end
111
111
 
112
112
  # Define a method called 'complete' on the singleton class.
113
- def self.completion(ary)
114
- self.send(:define_method,
115
- :complete,
116
- Proc.new {|prefix|
113
+ def self.completion(ary)
114
+ self.send(:define_method,
115
+ :complete,
116
+ Proc.new {|prefix|
117
117
  Trepan::Complete.complete_token(ary, prefix) })
118
118
  end
119
119