code: def EnsureGdbPosition(self, pid, tid, frame_depth):
      
      position = [pid, tid, frame_depth]
      if not pid:
        return
      if not self.IsAttached():
        try:
          self.Attach(position)
        except gdb.error as exc:
          raise PositionUnavailableException(exc.message)
      if gdb.selected_inferior().pid != pid:
        self.Detach()
        try:
          self.Attach(position)
        except gdb.error as exc:
          raise PositionUnavailableException(exc.message)
  
      if tid:
        tstate_head = GdbCache.INTERP_HEAD['tstate_head']
        for tstate in self._IterateChainedList(tstate_head, 'next'):
          if tid == tstate['thread_id']:
            self.selected_tstate = tstate
            break
        else:
          raise PositionUnavailableException('Thread %s does not exist.' %
                                             str(tid))
        stack_head = self.selected_tstate['frame']
        if frame_depth is not None:
          frames = list(self._IterateChainedList(stack_head, 'f_back'))
          frames.reverse()
          try:
            self.selected_frame = frames[frame_depth]
          except IndexError:
            raise PositionUnavailableException('Stack is not %s frames deep' %
                                               str(frame_depth + 1))
docs: Make sure our position matches the request.
  
      Args:
        pid: The process ID of the target process
        tid: The python thread ident of the target thread
        frame_depth: The 'depth' of the requested frame in the frame stack
      Raises:
        PositionUnavailableException: If the requested process, thread or frame
            can't be found or accessed.