Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-77370

QNetworkAccessManager get() method freezes the calling thread when internet access is down

    XMLWordPrintable

Details

    • Bug
    • Resolution: Cannot Reproduce
    • P3: Somewhat important
    • None
    • 5.12.4
    • Network
    • None
    • Windows 10 x64 1803
    • Windows

    Description

      Consider the following scenario:
      Use a computer with an ethernet connection with internet access with this setup:
      PC - ethernet cable 1- ethernet switch - ethernet cable 2 - internet gateway

      We do this so that Windows will not immediately detect that the ethernet interface is down when we unplug ethernet cable 2.

      Procedure: Now make sure you have internet access on your PC. Disable your ethernet interface, wait for a few seconds then enable it. Check that internet is working, then unplug ethernet cable 2, then launch the application.

      The application calls get() of QNetworkAccessManager then prints "Not frozen".

      The application hangs at the get() call of QNetworkAccessManager, the console won't output anything, if you try to exit it, it will display a mutex issue. Running it again will show "Not frozen".

      To reproduce again, perform again the procedure

      I have compiled this in debug mode and interrupted the process, here is the call stack:

       

      1  NtWaitForSingleObject                          ntdll                          0x7ffd67fcaa24 
      2  WaitForSingleObjectEx                          KERNELBASE                     0x7ffd64339252 
      3  QMutexPrivate::wait                            qmutex_win.cpp            64   0x7ffd1335bf5c 
      4  QBasicMutex::lockInternal                      qmutex.cpp                573  0x7ffd1335b8c4 
      5  QBasicMutex::lockInternal                      qmutex.cpp                490  0x7ffd1335b658 
      6  QBasicMutex::lock                              qmutex.h                  80   0x7ffd13320184 
      7  QRecursiveMutexPrivate::lock                   qmutex.cpp                707  0x7ffd1335d69f 
      8  QMutex::lock                                   qmutex.cpp                226  0x7ffd1335bd51 
      9  QMutexLocker::QMutexLocker                     qmutex.h                  207  0x7ffd1331a48d 
      10 QSslSocketPrivate::ensureLibraryLoaded         qsslsocket_openssl11.cpp  90   0x7ffd168cdbf1 
      11 QSslSocketPrivate::supportsSsl                 qsslsocket_openssl.cpp    497  0x7ffd168b7f79 
      12 QSslSocketPrivate::ensureInitialized           qsslsocket_openssl.cpp    509  0x7ffd168b7fe9 
      13 QSslConfigurationPrivate::defaultConfiguration qsslsocket.cpp            2280 0x7ffd168980fe 
      14 QSslConfiguration::defaultConfiguration        qsslconfiguration.cpp     1023 0x7ffd16887233 
      15 QNetworkRequest::sslConfiguration              qnetworkrequest.cpp       675  0x7ffd1671eccb 
      16 QNetworkReplyHttpImpl::QNetworkReplyHttpImpl   qnetworkreplyhttpimpl.cpp 193  0x7ffd167d04ae 
      17 QNetworkAccessManager::createRequest           qnetworkaccessmanager.cpp 1480 0x7ffd166f5f72 
      18 QNetworkAccessManager::post                    qnetworkaccessmanager.cpp 882  0x7ffd166f3f02 
      19 QNetworkAccessManager::post                    qnetworkaccessmanager.cpp 897  0x7ffd166f3fe9 
      20 ApiConnectorMgr::postPingData                  ApiConnectorMgr.cpp       572  0x7ff7815613ab 
      21 ApiConnectorMgr::updateCloudServerStatus       ApiConnectorMgr.cpp       1078 0x7ff7815614ce 
      22 ApiConnectorMgr::ApiConnectorMgr               ApiConnectorMgr.cpp       58   0x7ff781556f18 
      23 MainWindow::MainWindow                         mainwindow.cpp            121  0x7ff78143bbf8 
      24 main                                           main.cpp                  122  0x7ff781438636 
      25 invoke_main                                    exe_common.inl            65   0x7ff781598274 
      26 __scrt_common_main_seh                         exe_common.inl            253  0x7ff781598137 
      27 __scrt_common_main                             exe_common.inl            296  0x7ff781597ffe 
      28 mainCRTStartup                                 exe_main.cpp              17   0x7ff781598299 
      29 BaseThreadInitThunk                            KERNEL32                       0x7ffd67e54034 
      30 RtlUserThreadStart                             ntdll                          0x7ffd67fa3691 
      

      The lock seems to come from a QMutexLocker in qsslsocket_openssl11.cpp

      qsslsocket_openssl11.cpp line 83
      bool QSslSocketPrivate::ensureLibraryLoaded()
      {
          if (!q_resolveOpenSslSymbols())
              return false;
      
          const QMutexLocker locker(qt_opensslInitMutex);
      [interrupted here]
      ->   if (!s_libraryLoaded) {
              // Initialize OpenSSL.
              if (q_OPENSSL_init_ssl(0, nullptr) != 1)
                  return false;
              q_SSL_load_error_strings();
              q_OpenSSL_add_all_algorithms();
      
              QSslSocketBackendPrivate::s_indexForSSLExtraData
                  = q_CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, 0L, nullptr, nullptr,
                                              nullptr, nullptr);
      
              // Initialize OpenSSL's random seed.
              if (!q_RAND_status()) {
                  qWarning("Random number generator not seeded, disabling SSL support");
                  return false;
              }
      
              s_libraryLoaded = true;
          }
          return true;
      }
      

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            tpochep Timur Pocheptsov
            jojopirato Alban Deruaz-Pepin
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes