Bug #92325 Closed connections cause queries to hang forever
Submitted: 6 Sep 2018 19:30 Modified: 9 Nov 2018 17:03
Reporter: David Muchene Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / C++ Severity:S3 (Non-critical)
Version:8.0.12 OS:Linux
Assigned to: CPU Architecture:x86

[6 Sep 2018 19:30] David Muchene
Description:
If a connection is closed any attempt to read from the database results in infinite calls to read(). See comments in code below. Further there seems to be no way to set a timeout for such calls. 

void TLS::Read_op::do_wait()
{
  while (!is_completed()) //I THINK WE ARE STUCK HERE
    common_read(); 
}

bool TLS::Read_op::common_read()
{
  if (is_completed())
    return true;

  connection_TLS_impl& impl = m_tls.get_impl();

  const bytes& buffer = m_bufs.get_buffer(m_currentBufferIdx);
  byte* data =buffer.begin() + m_currentBufferOffset;
  int buffer_size = static_cast<int>(buffer.size() - m_currentBufferOffset);

  int result = SSL_read(impl.m_tls, data, buffer_size); //THIS BOILS DOWN to a BIO_Read()->sock_read()->read()...

  if (result == -1)
    throw IO_error(SSL_get_error(impl.m_tls,0));

  if (result > 0) //We got 0 bytes back because of the connection state... 
  {
    m_currentBufferOffset += result;

    if (m_currentBufferOffset == buffer.size())
    {
      ++m_currentBufferIdx;

      if (m_currentBufferIdx == m_bufs.buf_count())
      {
        set_completed(m_bufs.length());
        return true;
      }
    }
  }

  return false;
}

How to repeat:

//create a session
m_session = new Session("conection_str");

//restart the db

//query 
collection.find(std::string(search_string)).execute();

Suggested fix:

Provide a method for timing out queries.
[8 Oct 2018 13:24] MySQL Verification Team
HI,

It is not possible that the Connector is stuck where you are pointing, since it is very simple method.

You should either start checking your code for the return errors or exceptions or, when it gets stuck, you should KILL your program (compiled with full debug info) and send us a stacktrace.

Thanks in advance.
[9 Nov 2018 1:00] Bugs System
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
[9 Nov 2018 16:02] David Muchene
Hi, 
Sorry I've been away for a while and lost track of this issue. I'll submit the stack trace as soon as I can. Our code does check return codes and Exceptions the problem is there is no reason in the following snippet that result would be -1 in the scenario I described (i.e read returning 0), and so the calls never returns.

"int result = SSL_read(impl.m_tls, data, buffer_size);  
  if (result == -1)
    throw IO_error(SSL_get_error(impl.m_tls,0));
"

We got around it by adding some simple code after this snippet to check for 0 bytes returned and assume a disconnect after some period of time, so this issue is not currently blocking us.
[9 Nov 2018 17:03] MySQL Verification Team
That is the correct way of checking the particular function result.

You should read the documentation of how each different function or method works and how are the return values checked.

Closed.