Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

188 lines (162 sloc) 7.049 kB
# Copyright (C) 2010-2011, 2015 Rocky Bernstein <rockyb@rubyforge.net>
require_relative 'virtual'
class Trepan
class CmdProcessor < VirtualCmdProcessor
attr_accessor :stop_condition # String or nil. When not nil
# this has to eval non-nil
# in order to stop.
attr_accessor :stop_events # Set or nil. If not nil, only
# events in this set will be
# considered for stopping. This is
# like core.step_events (which
# could be used instead), but it is
# a set of event names rather than
# a bitmask and it is intended to
# be more temporarily changed via
# "step>" or "step!" commands.
attr_accessor :to_method
# Does whatever needs to be done to set to continue program
# execution.
# FIXME: turn line_number into a condition.
def continue
# FIXME: with the ruby-supported stepping, we might not
# need the below any more.
# I'm guessing the stack size can't ever reach this
@next_level = 32000
@next_thread = nil
if @settings[:traceprint]
@core.step_count = 1 # traceprint will avoid stopping
else
@core.step_count = -1 # No more event stepping
end
@leave_cmd_loop = true # Break out of the processor command loop.
end
# Does whatever setup needs to be done to set to ignore stepping
# to the finish of the current method.
def finish(level_count=0, opts={})
step(0, opts)
# @next_level = @frame.stack_size - level_count
# @next_thread = Thread.current
# @stop_events = Set.new(%w(return leave yield))
# Try high-speed (run-time-assisted) method
# FIXME: if frame is not the top frame, then we should to do more...
@frame.step_out
end
# Does whatever needs to be done to set to do "step over" or ignore
# stepping into methods called from this stack but step into any in
# the same level. We do this by keeping track of the number of
# stack frames and the current thread. Elsewhere in "skipping_step?"
# we do the checking.
def next(step_count=1, opts={})
step(step_count, opts)
# FIXME: if frame is not the top frame, then we should to do more...
# Try high-speed (run-time-assisted) method
@frame.step_over
# @next_level = @top_frame.stack_size
# @next_thread = Thread.current
end
# Does whatever needs to be done to set to step program
# execution.
def step(step_count=1, opts={}, condition=nil)
@frame.step_in if @frame
continue
@core.step_count = step_count
@different_pos = opts[:different_pos] if
opts.keys.member?(:different_pos)
@stop_condition = condition
@stop_events = opts[:stop_events] if
opts.keys.member?(:stop_events)
@to_method = opts[:to_method]
end
def quit(cmd='quit')
@next_level = 32000 # I'm guessing the stack size can't
# ever reach this
@next_thread = nil
@core.step_count = -1 # No more event stepping
@leave_cmd_loop = true # Break out of the processor command loop.
@settings[:autoirb] = false
@cmdloop_prehooks.delete_by_name('autoirb')
@commands['quit'].run([cmd])
end
def parse_next_step_suffix(step_cmd)
opts = {}
case step_cmd[-1..-1]
when '-'
opts[:different_pos] = false
when '+'
opts[:different_pos] = 'nostack'
when '='
opts[:different_pos] = true
when '!'
opts[:stop_events] = Set.new(%w(raise))
when '<'
opts[:stop_events] = Set.new(%w(c_return return))
when '>'
if step_cmd.size > 1 && step_cmd[-2..-2] == '<'
opts[:stop_events] = Set.new(%w(c_call c_return call return))
else
opts[:stop_events] = Set.new(%w(c_call call))
end
end
return opts
end
def running_initialize
@stop_condition = nil
@stop_events = nil
@to_method = nil
end
def stepping_skip?
return true if @core.step_count < 0
if @settings[:'debugskip']
msg "diff: #{@different_pos}, event : #{@event}, #{@stop_events.inspect}"
msg "step_count : #{@core.step_count}"
msg "next_level : #{@next_level}, ssize : #{@stack_size}"
msg "next_thread : #{@next_thread}, thread: #{Thread.current}"
end
# FIXME: with the ruby-supported stepping, we might not
# need @next_level an the below test.
return true if
!frame || (@next_level < @frame.stack_size &&
Thread.current == @next_thread && @event.to_s != 'raise')
new_pos = [@frame.source_container, frame_line,
@stack_size, @current_thread, @event, @frame.pc_offset]
skip_val = @stop_events && !@stop_events.member?(@event.to_s)
# If the last stop was a breakpoint, don't stop again if we are at
# the same location with a line event.
skip_val ||= (@last_pos[4] == 'brkpt' &&
@event.to_s == 'line' &&
@frame.pc_offset == @last_pos[5])
if @settings[:'debugskip']
puts "skip: #{skip_val.inspect}, last: #{@last_pos}, new: #{new_pos}"
end
@last_pos[2] = new_pos[2] if 'nostack' == @different_pos
unless skip_val
condition_met =
if @stop_condition
puts 'stop_cond' if @settings[:'debugskip']
debug_eval_no_errmsg(@stop_condition)
elsif @to_method
puts "method #{@frame.method} #{@to_method}" if
@settings[:'debugskip']
@frame.method == @to_method
else
puts 'uncond' if @settings[:'debugskip']
true
end
msg("condition_met: #{condition_met}, last: #{@last_pos}, " +
"new: #{new_pos}, different #{@different_pos.inspect}") if
@settings[:'debugskip']
skip_val = ((@last_pos[0..3] == new_pos[0..3] && @different_pos) ||
!condition_met)
end
@last_pos = new_pos if !@stop_events || @stop_events.member?(@event)
unless skip_val
# Set up the default values for the
# next time we consider skipping.
@different_pos = @settings[:different]
@stop_events = nil
end
return skip_val
end
end
end
Jump to Line
Something went wrong with that request. Please try again.