class DEBUGGER__::ThreadClient

def step_tp iter, events = [:line, :b_return, :return]

def step_tp iter, events = [:line, :b_return, :return]
  @step_tp.disable if @step_tp
  thread = Thread.current
  subsession_id = SESSION.subsession_id
  if SUPPORT_TARGET_THREAD
    @step_tp = TracePoint.new(*events){|tp|
      if SESSION.stop_stepping? tp.path, tp.lineno, subsession_id
        tp.disable
        next
      end
      next if !yield(tp)
      next if tp.path.start_with?(__dir__)
      next if tp.path.start_with?('<internal:trace_point>')
      next unless File.exist?(tp.path) if CONFIG[:skip_nosrc]
      loc = caller_locations(1, 1).first
      next if skip_location?(loc)
      next if iter && (iter -= 1) > 0
      tp.disable
      suspend tp.event, tp
    }
    @step_tp.enable(target_thread: thread)
  else
    @step_tp = TracePoint.new(*events){|tp|
      next if thread != Thread.current
      if SESSION.stop_stepping? tp.path, tp.lineno, subsession_id
        tp.disable
        next
      end
      next if !yield(tp)
      next if tp.path.start_with?(__dir__)
      next if tp.path.start_with?('<internal:trace_point>')
      next unless File.exist?(tp.path) if CONFIG[:skip_nosrc]
      loc = caller_locations(1, 1).first
      next if skip_location?(loc)
      next if iter && (iter -= 1) > 0
      tp.disable
      suspend tp.event, tp
    }
    @step_tp.enable
  end
end