class DEBUGGER__::ThreadClient

def show_frames max = nil, pattern = nil

def show_frames max = nil, pattern = nil
  if @target_frames && (max ||= @target_frames.size) > 0
    frames = []
    @target_frames.each_with_index{|f, i|
      # we need to use FrameInfo#matchable_location because #location_str is for display
      # and it may change based on configs (e.g. use_short_path)
      next if pattern && !(f.name.match?(pattern) || f.matchable_location.match?(pattern))
      # avoid using skip_path? because we still want to display internal frames
      next if skip_config_skip_path?(f.matchable_location)
      frames << [i, f]
    }
    size = frames.size
    max.times{|i|
      break unless frames[i]
      index, frame = frames[i]
      puts frame_str(index, frame: frame)
    }
    puts "  # and #{size - max} frames (use `bt' command for all frames)" if max < size
  end
end