Details
-
Bug
-
Resolution: Duplicate
-
P2: Important
-
None
-
5.14.2, 5.15.2
-
None
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
- duplicates
-
QTBUG-96057 Bluetooth crash when connectToPairedDevice on windows
- Closed