rb8-trepanning 0.1.5 → 0.1.6

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