trepanning 0.0.9 → 0.1.0
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.
- data/ChangeLog +237 -0
- data/NEWS +8 -0
- data/Rakefile +3 -2
- data/app/breakpoint.rb +8 -8
- data/app/brkptmgr.rb +86 -85
- data/app/client.rb +60 -0
- data/app/core.rb-consider +198 -0
- data/app/default.rb +17 -7
- data/app/disassemble.rb +12 -2
- data/app/options.rb +51 -20
- data/app/yarv.rb +183 -0
- data/bin/trepan +15 -9
- data/data/custom_require.rb +44 -0
- data/data/irbrc +41 -0
- data/data/prelude.rb +38 -0
- data/interface/base_intf.rb +10 -4
- data/interface/client.rb +79 -0
- data/interface/comcodes.rb +18 -0
- data/interface/server.rb +142 -0
- data/io/base_io.rb +57 -3
- data/io/tcpclient.rb +122 -0
- data/io/tcpfns.rb +31 -0
- data/io/tcpserver.rb +137 -0
- data/lib/trepanning.rb +57 -28
- data/processor/command/base/cmd.rb +10 -6
- data/processor/command/base/subcmd.rb +13 -1
- data/processor/command/directory.rb +15 -8
- data/processor/command/disassemble.rb +3 -2
- data/processor/command/help.rb +71 -19
- data/processor/command/info_subcmd/args.rb +2 -3
- data/processor/command/info_subcmd/breakpoints.rb +2 -3
- data/processor/command/info_subcmd/file.rb +2 -3
- data/processor/command/info_subcmd/frame.rb +2 -3
- data/processor/command/info_subcmd/iseq.rb +4 -5
- data/processor/command/info_subcmd/locals.rb +2 -3
- data/processor/command/info_subcmd/program.rb +2 -3
- data/processor/command/info_subcmd/registers.rb +2 -3
- data/processor/command/info_subcmd/return.rb +2 -3
- data/processor/command/info_subcmd/thread.rb +2 -3
- data/processor/command/list.rb +10 -6
- data/processor/command/reload.rb +1 -1
- data/processor/command/reload_subcmd/command.rb +29 -16
- data/processor/command/server.rb +70 -0
- data/processor/command/set_subcmd/auto.rb +2 -3
- data/processor/command/set_subcmd/basename.rb +2 -3
- data/processor/command/set_subcmd/debug.rb +2 -3
- data/processor/command/set_subcmd/different.rb +2 -3
- data/processor/command/set_subcmd/events.rb +2 -3
- data/processor/command/set_subcmd/hidelevel.rb +6 -7
- data/processor/command/set_subcmd/highlight.rb +32 -0
- data/processor/command/set_subcmd/max.rb +2 -3
- data/processor/command/set_subcmd/return.rb +2 -3
- data/processor/command/set_subcmd/sp.rb +2 -3
- data/processor/command/set_subcmd/substitute.rb +2 -3
- data/processor/command/set_subcmd/timer.rb +2 -3
- data/processor/command/set_subcmd/trace.rb +3 -4
- data/processor/command/show_subcmd/alias.rb +3 -3
- data/processor/command/show_subcmd/args.rb +2 -3
- data/processor/command/show_subcmd/auto.rb +1 -2
- data/processor/command/show_subcmd/basename.rb +2 -3
- data/processor/command/show_subcmd/debug.rb +1 -2
- data/processor/command/show_subcmd/different.rb +2 -1
- data/processor/command/show_subcmd/events.rb +2 -2
- data/processor/command/show_subcmd/hidelevel.rb +2 -3
- data/processor/command/show_subcmd/highlight.rb +23 -0
- data/processor/command/show_subcmd/macro.rb +2 -1
- data/processor/command/show_subcmd/max.rb +2 -3
- data/processor/command/show_subcmd/trace.rb +2 -3
- data/processor/command/source.rb +78 -28
- data/processor/default.rb +3 -2
- data/processor/load_cmds.rb +39 -19
- data/processor/location.rb +11 -7
- data/processor/main.rb +31 -15
- data/processor/mock.rb +22 -7
- data/processor/msg.rb +24 -8
- data/test/data/fname-with-blank.right +3 -0
- data/test/data/quit.right +2 -0
- data/test/functional/test-break-long.rb +87 -0
- data/test/functional/tmp/b3.rb +5 -0
- data/test/functional/tmp/immediate-bug1.rb +9 -0
- data/test/integration/helper.rb +14 -11
- data/test/integration/test-fname-with-blank.rb +5 -1
- data/test/integration/test-quit.rb +6 -2
- data/test/unit/cmd-helper.rb +9 -4
- data/test/unit/mock-helper.rb +9 -0
- data/test/unit/test-app-brkpt.rb +4 -4
- data/test/unit/test-app-brkptmgr.rb +2 -2
- data/test/unit/test-app-file.rb +0 -1
- data/test/unit/test-app-options.rb +26 -5
- data/test/unit/test-base-subcmd.rb +0 -1
- data/test/unit/test-cmd-alias.rb +0 -1
- data/test/unit/test-cmd-break.rb +0 -4
- data/test/unit/test-cmd-endisable.rb +1 -3
- data/test/unit/test-cmd-help.rb +0 -1
- data/test/unit/test-cmd-kill.rb +4 -5
- data/test/unit/test-cmd-quit.rb +4 -7
- data/test/unit/test-cmd-source.rb +33 -0
- data/test/unit/test-cmd-step.rb +0 -2
- data/test/unit/test-io-tcp.rb +32 -0
- data/test/unit/test-io-tcpclient.rb +53 -0
- data/test/unit/test-io-tcpserver.rb +49 -0
- data/test/unit/test-proc-main.rb +2 -2
- metadata +195 -175
- data/processor/command/stepi.rb +0 -63
- data/test/functional/tmp/b1.rb +0 -5
- data/test/functional/tmp/s1.rb +0 -9
- data/test/functional/tmp/t2.rb +0 -6
- data/test/integration/try-test-enable.rb +0 -11
data/processor/default.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
1
|
+
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
require_relative '../app/default'
|
3
3
|
class Trepan
|
4
4
|
class CmdProcessor
|
@@ -23,6 +23,7 @@ class Trepan
|
|
23
23
|
# nil or -1 means compute value. 0
|
24
24
|
# means hide none. Less than 0 means show
|
25
25
|
# all stack entries.
|
26
|
+
:hightlight => false, # Use terminal highlight?
|
26
27
|
:maxlist => 10, # Number of source lines to list
|
27
28
|
:maxstack => 10, # backtrace limit
|
28
29
|
:maxstring => 150, # Strings which are larger than this
|
@@ -36,7 +37,7 @@ class Trepan
|
|
36
37
|
:timer => false, # show elapsed time between events
|
37
38
|
:traceprint => false, # event tracing printing
|
38
39
|
:tracebuffer => false, # save events to a trace buffer.
|
39
|
-
:user_cmd_dir => File.join(
|
40
|
+
:user_cmd_dir => File.join(Trepan::HOME_DIR, 'tepanx', 'command'),
|
40
41
|
# User command directory
|
41
42
|
}
|
42
43
|
end
|
data/processor/load_cmds.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
1
|
+
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
# Trepan::CmdProcess that loads up debugger commands from builtin and
|
3
3
|
# user directories.
|
4
4
|
# Sets @commands, @aliases, @macros
|
@@ -29,28 +29,48 @@ class Trepan
|
|
29
29
|
# 'command' directory. Then a new instance of each class of the
|
30
30
|
# form Trepan::xxCommand is added to @commands and that array
|
31
31
|
# is returned.
|
32
|
+
def load_debugger_commands(file_or_dir)
|
33
|
+
if File.directory?(file_or_dir)
|
34
|
+
Dir.glob(File.join(file_or_dir, '*.rb')).each do |rb|
|
35
|
+
# We use require so that multiple calls have no effect.
|
36
|
+
require rb
|
37
|
+
end
|
38
|
+
elsif File.readable?(file_or_dir)
|
39
|
+
# We use load in case we are reloading.
|
40
|
+
# 'require' would not be effective here
|
41
|
+
load file_or_dir
|
42
|
+
else
|
43
|
+
return false
|
44
|
+
end
|
45
|
+
Trepan::Command.constants.grep(/.Command$/).each do |command|
|
46
|
+
setup_command(command)
|
47
|
+
end
|
48
|
+
return true
|
49
|
+
end
|
32
50
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
end if File.directory?(cmd_dir)
|
37
|
-
# Instantiate each Command class found by the above require(s).
|
38
|
-
### p Trepan::Command.constants ## REMOVE ME
|
51
|
+
def load_debugger_command(command_file)
|
52
|
+
return unless File.readable?(command_file)
|
53
|
+
load command_file
|
39
54
|
Trepan::Command.constants.grep(/.Command$/).each do |command|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
cmd = self.instance_eval(new_cmd)
|
55
|
+
setup_command(command)
|
56
|
+
end
|
57
|
+
end
|
44
58
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
59
|
+
# Instantiate a Trepan::Command and extract info: the NAME, ALIASES
|
60
|
+
# and store the command in @commands.
|
61
|
+
def setup_command(command)
|
62
|
+
# Note: there is probably a non-eval way to instantiate the
|
63
|
+
# command, but I don't know it. And eval works.
|
64
|
+
klass = self.instance_eval("Trepan::Command::#{command}")
|
65
|
+
cmd = klass.send(:new, self)
|
66
|
+
|
67
|
+
# Add to list of commands and aliases.
|
68
|
+
cmd_name = klass.const_get(:NAME)
|
69
|
+
if klass.constants.member?(:ALIASES)
|
70
|
+
aliases= klass.const_get(:ALIASES)
|
71
|
+
aliases.each {|a| @aliases[a] = cmd_name}
|
53
72
|
end
|
73
|
+
@commands[cmd_name] = cmd
|
54
74
|
end
|
55
75
|
|
56
76
|
# Looks up cmd_array[0] in @commands and runs that. We do lots of
|
data/processor/location.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
1
|
+
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
require 'linecache'
|
3
3
|
require_relative 'msg'
|
4
4
|
require_relative '../app/frame'
|
@@ -42,15 +42,18 @@ class Trepan
|
|
42
42
|
# Get line +line_number+ from file named +filename+. Return ''
|
43
43
|
# if there was a problem. Leading blanks are stripped off.
|
44
44
|
def line_at(filename, line_number) # :nodoc:
|
45
|
-
|
45
|
+
opts = {
|
46
|
+
:reload_on_change => @reload_on_change,
|
47
|
+
:output => @settings[:highlight]
|
48
|
+
}
|
49
|
+
line = LineCache::getline(filename, line_number, opts)
|
46
50
|
|
47
51
|
unless line
|
48
52
|
# Try using search directories (set with command "directory")
|
49
53
|
if filename[0..0] != File::SEPARATOR
|
50
54
|
try_filename = resolve_file_with_dir(filename)
|
51
55
|
if try_filename &&
|
52
|
-
line = LineCache::getline(try_filename, line_number,
|
53
|
-
@reload_on_change)
|
56
|
+
line = LineCache::getline(try_filename, line_number, opts)
|
54
57
|
LineCache::remap_file(filename, try_filename)
|
55
58
|
end
|
56
59
|
end
|
@@ -61,7 +64,7 @@ class Trepan
|
|
61
64
|
def loc_and_text(loc, frame, line_no, source_container)
|
62
65
|
found_line = true
|
63
66
|
## FIXME: condition is too long.
|
64
|
-
if source_container[0] == 'string' && frame.iseq && frame.iseq.
|
67
|
+
if source_container[0] == 'string' && frame.iseq && frame.iseq.eval_source
|
65
68
|
file = LineCache::map_iseq(frame.iseq)
|
66
69
|
text = LineCache::getline(frame.iseq, line_no)
|
67
70
|
loc += " remapped #{canonic_file(file)}:#{line_no}"
|
@@ -138,8 +141,9 @@ class Trepan
|
|
138
141
|
filename = source_container[1]
|
139
142
|
## FIXME: condition is too long.
|
140
143
|
canonic_filename =
|
141
|
-
if 'string' == source_container[0] && frame.iseq &&
|
142
|
-
|
144
|
+
if 'string' == source_container[0] && frame.iseq &&
|
145
|
+
frame.iseq.eval_source
|
146
|
+
eval_str = frame.iseq.eval_source
|
143
147
|
'eval "' + safe_repr(eval_str.gsub(/\n/,';'), 15) + '"'
|
144
148
|
else
|
145
149
|
canonic_file(filename)
|
data/processor/main.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
-
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
1
|
+
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
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
|
-
require 'linecache'
|
6
5
|
require 'set'
|
7
6
|
require 'pathname' # For cleanpath
|
8
7
|
|
@@ -22,6 +21,7 @@ class Trepan
|
|
22
21
|
# This is current_command with the command
|
23
22
|
# name removed from the beginning.
|
24
23
|
attr_reader :cmd_name # command name before alias or macro resolution
|
24
|
+
attr_reader :cmd_queue # queue of commands to run
|
25
25
|
attr_reader :core # Trepan core object
|
26
26
|
attr_reader :current_command # Current command getting run, a String.
|
27
27
|
attr_reader :dbgr # Trepan instance (via
|
@@ -59,6 +59,7 @@ class Trepan
|
|
59
59
|
# Event icons used in printing locations.
|
60
60
|
EVENT2ICON = {
|
61
61
|
'brkpt' => 'xx',
|
62
|
+
'tbrkpt' => 'x1',
|
62
63
|
'c-call' => 'C>',
|
63
64
|
'c-return' => '<C',
|
64
65
|
'call' => '->',
|
@@ -81,6 +82,7 @@ class Trepan
|
|
81
82
|
end
|
82
83
|
|
83
84
|
def initialize(core, settings={})
|
85
|
+
@cmd_queue = []
|
84
86
|
@core = core
|
85
87
|
@debug_nest = 1
|
86
88
|
@dbgr = core.dbgr
|
@@ -93,7 +95,7 @@ class Trepan
|
|
93
95
|
start_cmds = settings.delete(:start_cmds)
|
94
96
|
start_file = settings.delete(:start_file)
|
95
97
|
|
96
|
-
@settings =
|
98
|
+
@settings = DEFAULT_SETTINGS.merge(settings)
|
97
99
|
@different_pos = @settings[:different]
|
98
100
|
|
99
101
|
# FIXME: Rework using a general "set substitute file" command and
|
@@ -167,13 +169,19 @@ class Trepan
|
|
167
169
|
|
168
170
|
# Run one debugger command. True is returned if we want to quit.
|
169
171
|
def process_command_and_quit?()
|
170
|
-
|
171
|
-
|
172
|
-
|
172
|
+
intf_size = @dbgr.intf.size
|
173
|
+
intf = @dbgr.intf[-1]
|
174
|
+
return true if intf.input_eof? && intf_size == 1
|
175
|
+
while intf_size > 1 || !intf.input_eof?
|
173
176
|
begin
|
174
|
-
@current_command =
|
177
|
+
@current_command =
|
178
|
+
if @cmd_queue.empty?
|
179
|
+
read_command.strip
|
180
|
+
else
|
181
|
+
@cmd_queue.shift
|
182
|
+
end
|
175
183
|
if @current_command.empty?
|
176
|
-
if @last_command && intf
|
184
|
+
if @last_command && intf.interactive?
|
177
185
|
@current_command = @last_command
|
178
186
|
else
|
179
187
|
next
|
@@ -181,13 +189,15 @@ class Trepan
|
|
181
189
|
end
|
182
190
|
next if @current_command[0..0] == '#' # Skip comment lines
|
183
191
|
break
|
184
|
-
rescue IOError, Errno::EPIPE
|
185
|
-
if
|
186
|
-
@dbgr.intf.pop
|
192
|
+
rescue IOError, Errno::EPIPE => e
|
193
|
+
if intf_size > 1
|
194
|
+
@dbgr.intf.pop
|
195
|
+
intf_size = @dbgr.intf.size
|
196
|
+
intf = @dbgr.intf[-1]
|
187
197
|
@last_command = nil
|
188
198
|
print_location
|
189
199
|
else
|
190
|
-
msg "
|
200
|
+
msg "That's all folks..."
|
191
201
|
## FIXME: think of something better.
|
192
202
|
quit('quit!')
|
193
203
|
return true
|
@@ -230,7 +240,7 @@ class Trepan
|
|
230
240
|
@dbgr.stop
|
231
241
|
raise
|
232
242
|
rescue Exception => exc
|
233
|
-
|
243
|
+
errmsg("Internal debugger error: #{exc.inspect}")
|
234
244
|
exception_dump(exc, @settings[:debugexcept], $!.backtrace)
|
235
245
|
end
|
236
246
|
end
|
@@ -248,16 +258,22 @@ class Trepan
|
|
248
258
|
end
|
249
259
|
|
250
260
|
unless eval_command
|
251
|
-
|
261
|
+
commands = current_command.split(';;')
|
262
|
+
if commands.size > 1
|
263
|
+
current_command = commands.shift
|
264
|
+
@cmd_queue.unshift *commands
|
265
|
+
end
|
252
266
|
args = current_command.split
|
267
|
+
# Expand macros. FIXME: put in a procedure
|
253
268
|
while true do
|
254
269
|
macro_cmd_name = args[0]
|
255
270
|
return false if args.size == 0
|
256
271
|
break unless @macros.member?(macro_cmd_name)
|
257
272
|
current_command = @macros[macro_cmd_name].call(*args[1..-1])
|
258
273
|
msg current_command if settings[:debugmacro]
|
274
|
+
# FIXME: should handle nested Array as a new command.
|
259
275
|
if current_command.is_a?(Array) &&
|
260
|
-
current_command.
|
276
|
+
current_command.all? {|val| val.is_a?(String)}
|
261
277
|
args = current_command
|
262
278
|
elsif current_command.is_a?(String)
|
263
279
|
args = current_command.split
|
data/processor/mock.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
1
|
+
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
# Mock setup for commands.
|
3
3
|
require_relative 'main'
|
4
|
+
|
4
5
|
require_relative '../app/core'
|
5
6
|
require_relative '../app/default'
|
7
|
+
require_relative '../app/frame'
|
6
8
|
require_relative '../interface/user' # user interface (includes I/O)
|
7
9
|
|
8
10
|
SCRIPT_ISEQS__ = {} unless
|
@@ -14,6 +16,7 @@ module MockDebugger
|
|
14
16
|
class MockDebugger
|
15
17
|
attr_accessor :trace_filter # Procs/Methods we ignore.
|
16
18
|
|
19
|
+
attr_accessor :frame # Actually a "Rubinius::Location object
|
17
20
|
attr_accessor :core # access to Debugger::Core instance
|
18
21
|
attr_accessor :intf # The way the outside world interfaces with us.
|
19
22
|
attr_reader :initial_dir # String. Current directory when program
|
@@ -21,10 +24,16 @@ module MockDebugger
|
|
21
24
|
attr_accessor :restart_argv # How to restart us, empty or nil.
|
22
25
|
# Note restart[0] is typically $0.
|
23
26
|
attr_reader :settings # Hash[:symbol] of things you can configure
|
27
|
+
attr_accessor :processor
|
28
|
+
|
29
|
+
# FIXME: move more stuff of here and into Trepan::CmdProcessor
|
30
|
+
# These below should go into Trepan::CmdProcessor.
|
31
|
+
attr_reader :cmd_argstr, :cmd_name, :vm_locations, :current_frame,
|
32
|
+
:debugee_thread
|
24
33
|
|
25
34
|
def initialize(settings={})
|
26
35
|
@before_cmdloop_hooks = []
|
27
|
-
@settings =
|
36
|
+
@settings = Trepan::DEFAULT_SETTINGS.merge(settings)
|
28
37
|
@intf = [Trepan::UserInterface.new]
|
29
38
|
@core = Trepan::Core.new(self)
|
30
39
|
@trace_filter = []
|
@@ -34,6 +43,9 @@ module MockDebugger
|
|
34
43
|
|
35
44
|
end
|
36
45
|
|
46
|
+
def frame(num)
|
47
|
+
@frames[num] ||= Trepan::Frame.new(self, num, @vm_locations[num])
|
48
|
+
end
|
37
49
|
end
|
38
50
|
|
39
51
|
# Common Mock debugger setup
|
@@ -55,17 +67,20 @@ module MockDebugger
|
|
55
67
|
cmd.proc.frame_setup(RubyVM::ThreadFrame::current.prev)
|
56
68
|
show_special_class_constants(cmd) if show_constants
|
57
69
|
|
70
|
+
def cmd.confirm(prompt, default)
|
71
|
+
true
|
72
|
+
end
|
73
|
+
def cmd.errmsg(message)
|
74
|
+
puts "Error: #{message}"
|
75
|
+
end
|
58
76
|
def cmd.msg(message)
|
59
77
|
puts message
|
60
78
|
end
|
61
79
|
def cmd.msg_nocr(message)
|
62
80
|
print message
|
63
81
|
end
|
64
|
-
def cmd.
|
65
|
-
puts "
|
66
|
-
end
|
67
|
-
def cmd.confirm(prompt, default)
|
68
|
-
true
|
82
|
+
def cmd.section(message, opts={})
|
83
|
+
puts "Section: #{message}"
|
69
84
|
end
|
70
85
|
|
71
86
|
return dbgr, cmd
|
data/processor/msg.rb
CHANGED
@@ -1,18 +1,25 @@
|
|
1
|
-
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
1
|
+
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
# I/O related command processor methods
|
3
3
|
require_relative '../app/util'
|
4
4
|
class Trepan
|
5
5
|
class CmdProcessor
|
6
|
-
def errmsg(message)
|
7
|
-
|
6
|
+
def errmsg(message, opts={})
|
7
|
+
message = safe_rep(message) unless opts[:unlimited]
|
8
|
+
if @settings[:highlight] && defined?(Term::ANSIColor)
|
9
|
+
message =
|
10
|
+
Term::ANSIColor.italic + message + Term::ANSIColor.reset
|
11
|
+
end
|
12
|
+
@dbgr.intf[-1].errmsg(message)
|
8
13
|
end
|
9
14
|
|
10
|
-
def msg(message)
|
11
|
-
|
15
|
+
def msg(message, opts={})
|
16
|
+
message = safe_rep(message) unless opts[:unlimited]
|
17
|
+
@dbgr.intf[-1].msg(message)
|
12
18
|
end
|
13
19
|
|
14
|
-
def msg_nocr(message)
|
15
|
-
|
20
|
+
def msg_nocr(message, opts={})
|
21
|
+
message = safe_rep(message) unless opts[:unlimited]
|
22
|
+
@dbgr.intf[-1].msg_nocr(message)
|
16
23
|
end
|
17
24
|
|
18
25
|
def read_command()
|
@@ -20,7 +27,16 @@ class Trepan
|
|
20
27
|
end
|
21
28
|
|
22
29
|
def safe_rep(str)
|
23
|
-
|
30
|
+
Util::safe_repr(str, @settings[:maxstring])
|
31
|
+
end
|
32
|
+
|
33
|
+
def section(message, opts={})
|
34
|
+
message = safe_rep(message) unless opts[:unlimited]
|
35
|
+
if @settings[:highlight] && defined?(Term::ANSIColor)
|
36
|
+
message =
|
37
|
+
Term::ANSIColor.bold + message + Term::ANSIColor.reset
|
38
|
+
end
|
39
|
+
@dbgr.intf[-1].msg(message)
|
24
40
|
end
|
25
41
|
end
|
26
42
|
end
|
data/test/data/quit.right
CHANGED
@@ -0,0 +1,87 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'test/unit'
|
3
|
+
require 'trace'
|
4
|
+
require_relative 'fn_helper'
|
5
|
+
require_relative '../../app/breakpoint'
|
6
|
+
|
7
|
+
class TestBreak < Test::Unit::TestCase
|
8
|
+
|
9
|
+
include FnTestHelper
|
10
|
+
|
11
|
+
def setup
|
12
|
+
Trepan::Breakpoint::reset
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_break_same_level
|
16
|
+
|
17
|
+
# See that we can stop at a breakpoint
|
18
|
+
cmds = ['set basename on',
|
19
|
+
'break ' + (__LINE__ + 7).to_s,
|
20
|
+
'continue']
|
21
|
+
d = strarray_setup(cmds)
|
22
|
+
d.start
|
23
|
+
########### b1 ###############
|
24
|
+
x = 5
|
25
|
+
y = 6
|
26
|
+
z = 7
|
27
|
+
##############################
|
28
|
+
d.stop
|
29
|
+
out = ['-- ',
|
30
|
+
'x = 5',
|
31
|
+
'basename is on.',
|
32
|
+
"Breakpoint 1 set at line 55 in file foo.rb,
|
33
|
+
\tVM offset 55 of instruction sequence \"test_break_same_level\".",
|
34
|
+
'xx ',
|
35
|
+
'z = 7']
|
36
|
+
compare_output(out, d, cmds)
|
37
|
+
|
38
|
+
# Try a disabling the breakpoint
|
39
|
+
cmds = ['set basename on',
|
40
|
+
'break ' + (__LINE__ + 8).to_s,
|
41
|
+
'break ' + (__LINE__ + 8).to_s,
|
42
|
+
'disable 1',
|
43
|
+
'continue']
|
44
|
+
d = strarray_setup(cmds)
|
45
|
+
d.start
|
46
|
+
########### b2 ###############
|
47
|
+
x = 7
|
48
|
+
y = 8
|
49
|
+
z = 8+1
|
50
|
+
##############################
|
51
|
+
d.stop
|
52
|
+
out = ['-- ',
|
53
|
+
'x = 7',
|
54
|
+
"basename is on.",
|
55
|
+
"Breakpoint 1 set at line 55 in file foo.rb,
|
56
|
+
\tVM offset 55 of instruction sequence \"test_break_same_level\".",
|
57
|
+
"Breakpoint 2 set at line 55 in file foo.rb,
|
58
|
+
\tVM offset 55 of instruction sequence \"test_break_same_level\".",
|
59
|
+
"Breakpoint 1 disabled.",
|
60
|
+
'xx ',
|
61
|
+
'z = 8+1']
|
62
|
+
compare_output(out, d, cmds)
|
63
|
+
|
64
|
+
# Stepping after a breakpoint should not stay at same location.
|
65
|
+
cmds = ['set basename on',
|
66
|
+
'continue ' + (__LINE__ + 8).to_s,
|
67
|
+
'continue']
|
68
|
+
dbg = strarray_setup(cmds)
|
69
|
+
dbg.start
|
70
|
+
########### b3 ###############
|
71
|
+
a = 1
|
72
|
+
b = 2
|
73
|
+
c = 3
|
74
|
+
d = 4
|
75
|
+
e = 5
|
76
|
+
##############################
|
77
|
+
dbg.stop
|
78
|
+
out = ['-- ',
|
79
|
+
'a = 1',
|
80
|
+
'basename is on.',
|
81
|
+
'xx ',
|
82
|
+
'd = 4' ]
|
83
|
+
compare_output(out, dbg, cmds)
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|