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

Crash on Windows when erasing QLowEnergyController during activity

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P2: Important
    • Resolution: Duplicate
    • Affects Version/s: 5.14.2, 5.15.2
    • Fix Version/s: None
    • Labels:
      None
    • Platform/s:
      Windows

      Description

      When using the Qt Bluetooth Low Energy, the expectation is to be able to stop the services at any time (for example due to custom timeout or disconnect button press) and afterwards delete the leftover variables (to avoid memory leaks).

      On Windows the QLowEnergyController (and its QLowEnergyService) does not seems to be properly cleaned when trying to stop it during activity. There remains some leftover threads which will later crash the application if the underlying QLowEnergyController was deleted. Even calling disconnectFromDevice() and waiting on the disconnected() signal and then deleting does not works -> the QLowEnergyController reports it has stopped and that it is in invalid state, but it will crash anyway if deleted too soon. Using deleteLater() instead of delete to ensure there is not some pending event also does not helps.

      The only reasonable solution so far is to not stop anything, leave the ongoing Bluetooth activity until it is finished (hoping it actually finishes at some point) and then deleting the QLowEnergyController once idle.

      The crash can vary depending on activity (but it always is somewhere in qlowenergycontroller_winrt_new), for example deleting during discoverDetails() of underlying QLowEnergyService looks like this:

      1  QUuid::isNull                                                                                                                                                                                                                                         quuid.cpp                          869  0x7ffa54302dc7 
      2  QUuid::variant                                                                                                                                                                                                                                        quuid.cpp                          918  0x7ffa543031e3 
      3  QUuid::operator<                                                                                                                                                                                                                                      quuid.cpp                          962  0x7ffa54302ee8 
      4  qMapLessThanKey<QBluetoothUuid>                                                                                                                                                                                                                       qmap.h                             69   0x7ffa7437127e 
      5  QMapNode<QBluetoothUuid,QSharedPointer<QLowEnergyServicePrivate>>::lowerBound                                                                                                                                                                         qmap.h                             152  0x7ffa743721cf 
      6  QMapData<QBluetoothUuid,QSharedPointer<QLowEnergyServicePrivate>>::findNode                                                                                                                                                                           qmap.h                             284  0x7ffa74372024 
      7  QMap<QBluetoothUuid,QSharedPointer<QLowEnergyServicePrivate>>::contains                                                                                                                                                                               qmap.h                             703  0x7ffa7437560a 
      8  <lambda_d40dd57eba7cd0c86b381273017b63ee>::operator()                                                                                                                                                                                                 qlowenergycontroller_winrt_new.cpp 922  0x7ffa7441335a 
      9  QtPrivate::FunctorCall<QtPrivate::IndexesList<0,1,2,3,4>,QtPrivate::List<QBluetoothUuid const &,QHash<unsigned short,QLowEnergyServicePrivate::CharData>,QVector<QBluetoothUuid>,unsigned short,unsigned short>,void,<lambda_d40dd57eba7cd0c86b381273 qobjectdefs_impl.h                 146  0x7ffa74417471 
      10 QtPrivate::Functor<<lambda_d40dd57eba7cd0c86b381273017b63ee>,5>::call<QtPrivate::List<QBluetoothUuid const &,QHash<unsigned short,QLowEnergyServicePrivate::CharData>,QVector<QBluetoothUuid>,unsigned short,unsigned short>,void>                    qobjectdefs_impl.h                 257  0x7ffa74402612 
      11 QtPrivate::QFunctorSlotObject<<lambda_d40dd57eba7cd0c86b381273017b63ee>,5,QtPrivate::List<QBluetoothUuid const &,QHash<unsigned short,QLowEnergyServicePrivate::CharData>,QVector<QBluetoothUuid>,unsigned short,unsigned short>,void>::impl          qobjectdefs_impl.h                 449  0x7ffa74417f0d 
      12 QtPrivate::QSlotObjectBase::call                                                                                                                                                                                                                      qobjectdefs_impl.h                 398  0x7ffa5432e9d2 
      13 doActivate<0>                                                                                                                                                                                                                                         qobject.cpp                        3886 0x7ffa54386bb8 
      14 QMetaObject::activate                                                                                                                                                                                                                                 qobject.cpp                        3947 0x7ffa543736d7 
      15 QWinRTLowEnergyServiceHandlerNew::charListObtained                                                                                                                                                                                                    qlowenergycontroller_winrt_new.moc 181  0x7ffa743fab31 
      16 QWinRTLowEnergyServiceHandlerNew::checkAllCharacteristicsDiscovered                                                                                                                                                                                   qlowenergycontroller_winrt_new.cpp 417  0x7ffa743fa9e7 
      17 <lambda_95f181697485bd74a6844f8c0a9e96f8>::operator()                                                                                                                                                                                                 qlowenergycontroller_winrt_new.cpp 379  0x7ffa7440febe 
      18 Microsoft::WRL::Details::DelegateArgTraits<long (__cdecl ABI::Windows::Foundation::IAsyncOperationCompletedHandler_impl<ABI::Windows::Foundation::Internal::AggregateType<ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::GattDescriptorsR event.h                            245  0x7ffa74415c17 
      19 Windows::Internal::AsyncBaseFTM<Windows::Foundation::IAsyncOperationCompletedHandler<Windows::Devices::Bluetooth::GenericAttributeProfile::GattDescriptorsResult * __ptr64>,1,Microsoft::WRL::AsyncOptions<-1,0,&GUID_CAUSALITY_WINDOWS_P             Windows_Devices_Bluetooth               0x7ffa85609ade 
      20 Windows::Internal::AsyncOperation<Windows::Foundation::IAsyncOperation<Windows::Devices::Bluetooth::GenericAttributeProfile::GattDescriptorsResult * __ptr64>,Windows::Foundation::IAsyncOperationCompletedHandler<Windows::Devices::Blue             Windows_Devices_Bluetooth               0x7ffa8560d441 
      21 Windows::Internal::AsyncOperation<Windows::Foundation::IAsyncOperation<Windows::Devices::Bluetooth::GenericAttributeProfile::GattDescriptorsResult * __ptr64>,Windows::Foundation::IAsyncOperationCompletedHandler<Windows::Devices::Blue             Windows_Devices_Bluetooth               0x7ffa8560a359 
      22 WorkThreadManager::CThread::ThreadProc                                                                                                                                                                                                                shcore                                  0x7ffaa6cd817e 
      23 WorkThreadManager::CThread::s_ExecuteThreadProc                                                                                                                                                                                                       shcore                                  0x7ffaa6cd7e14 
      24 <lambda_5756e8f27281b3936b1260d598265791>::<lambda_invoker_cdecl>                                                                                                                                                                                     shcore                                  0x7ffaa6cd79a1 
      25 BaseThreadInitThunk                                                                                                                                                                                                                                   KERNEL32                                0x7ffaa7267974 
      26 RtlUserThreadStart  
      

      How to reproduce: the simplest way is to use the low energy scanner example and interrupt activity, for example interrupting the discoverDetails() in device.cpp:

          if (service->state() == QLowEnergyService::DiscoveryRequired) {
              //! [les-service-3]
              connect(service, &QLowEnergyService::stateChanged,
                      this, &Device::serviceDetailsDiscovered);
              service->discoverDetails();
              setUpdate("Back\n(Discovering details...)");
              //! [les-service-3]
      
      +        QTimer::singleShot(
      +                    100, this, [&]() {
      +            if (controller) {
      +                disconnectFromDevice();
      +                delete controller;
      +                controller = nullptr;
      +            }
      +        });
      +
              return;
          }
      

      Note: This bug is reproducible only on Windows (did not reproduced on MacOS)

        Attachments

          Issue Links

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

            Activity

              People

              Assignee:
              ablasche Alex Blasche
              Reporter:
              rastislav_kamenicky Rastislav Kamenicky
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:

                  Gerrit Reviews

                  There are no open Gerrit changes