docs: def _Recv(self, timeout):
      """Receive output from gdb.
  
      This reads gdb's stdout and stderr streams, returns a single line of gdb's
      stdout or rethrows any exceptions thrown from within gdb as well as it can.
  
      Args:
        timeout: floating point number of seconds after which to abort.
            A value of None or TIMEOUT_FOREVER means "there is no timeout", i.e.
            this might block forever.
      Raises:
        ProxyError: All exceptions received from the gdb service are generically
            reraised as this.
        TimeoutError: Raised if no answer is received from gdb in after the
            specified time.
      Returns:
        The current contents of gdb's stdout buffer, read until the next newline,
        or `None`, should the read fail or timeout.
      """
  
      buf = ''
      # The messiness of this stems from the "duck-typiness" of this function.
      # The timeout parameter of poll has different semantics depending on whether
      # it's <=0, >0, or None. Yay.
  
      wait_for_line = timeout is TIMEOUT_FOREVER
      deadline = time.time() + (timeout if not wait_for_line else 0)
  
      def TimeLeft():
        return max(1000 * (deadline - time.time()), 0)
  
      continue_reading = True
  
      while continue_reading:
        poll_timeout = None if wait_for_line else TimeLeft()
  
        fd_list = [event[0] for event in self._poller.poll(poll_timeout)
                   if event[1] & (select.POLLIN | select.POLLPRI)]
        if not wait_for_line and TimeLeft() == 0:
          continue_reading = False
        if self._outfile_r.fileno() in fd_list:
          buf += self._outfile_r.readline()
          if buf.endswith('\n'):
            return buf
  
        # GDB-internal exception passing
        if self._errfile_r.fileno() in fd_list:
          exc = self._errfile_r.readline()
          if exc:
            exc_text = '\n-----------------------------------\n'
            exc_text += 'Error occurred within GdbService:\n'
            try:
              exc_text += json.loads(exc)
            except ValueError:
              # whatever we got back wasn't valid JSON.
              # This usually means we've run into an exception before the special
              # exception handling was turned on. The first line we read up there
              # will have been "Traceback (most recent call last):". Obviously, we
              # want the rest, too, so we wait a bit and read it.
              deadline = time.time() + 0.5
              while self.is_running and TimeLeft() > 0:
                exc += self._errfile_r.read()
              try:
                exc_text += json.loads(exc)
              except ValueError:
                exc_text = exc
            raise ProxyError(exc_text)
      # timeout
      raise TimeoutError()