Details
Description
From our users crash reports found(there is no steps)
Thread 42 Crashed: 0 QtCore 0x0000000106bfaa2c void doActivate<false>(QObject*, int, void**) (qobject.cpp:3968) 1 QtNetwork 0x0000000104ebbec0 QNetworkConnectionMonitor::reachabilityChanged(bool) (moc_qnetconmonitor_p.cpp:141) 2 SystemConfiguration 0x0000000192542e88 reachPerformAndUnlock + 616 3 Network 0x00000001985325e0 __nw_path_necp_update_evaluator_block_invoke + 468 4 libdispatch.dylib 0x00000001916c2874 _dispatch_call_block_and_release + 28 5 libdispatch.dylib 0x00000001916c4400 _dispatch_client_callout + 16 6 libdispatch.dylib 0x00000001916cba88 _dispatch_lane_serial_drain + 664 7 libdispatch.dylib 0x00000001916cc5f8 _dispatch_lane_invoke + 380 8 libdispatch.dylib 0x00000001916d7244 _dispatch_workloop_worker_thread + 644 9 libsystem_pthread.dylib 0x0000000191870074 _pthread_wqthread + 284 10 libsystem_pthread.dylib 0x000000019186ed94 start_wqthread + 4
After some digging found possible race condition in qnetconmonitor_darwin.mm:
QNetworkConnectionMonitorPrivate::updateState
and
QNetworkConnectionMonitor::stopMonitoring()
can be called from different threads
For me on simple example:
int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QNetworkAccessManager manager; QObject::connect(&manager, &QNetworkAccessManager::finished, &manager, [&a](QNetworkReply *reply){ qDebug() << "Reply finished with code = " << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toUInt(); }); manager.get(QNetworkRequest(QUrl("http://qt-project.org"))); return a.exec(); }
bool QNetworkConnectionMonitor::startMonitoring()
void QNetworkConnectionMonitor::stopMonitoring() (through QNetworkConnectionMonitor::~QNetworkConnectionMonitor)
were called from thread
#10081256 QNetworkAccessManager thread
and if turn off network I've got
void QNetworkConnectionMonitorPrivate::probeCallback(SCNetworkReachabilityRef probe, SCNetworkReachabilityFlags flags, void *info)
called from thread:
#10081254 None
It is possible to get crash if
QNetworkConnectionMonitorPrivate::updateState
was called through QNetworkConnectionMonitorPrivate::probeCallback from one thread and QNetworkConnectionMonitor::stopMonitoring() through QNetworkConnectionMonitor::~QNetworkConnectionMonitor() from another thread
Attachments
For Gerrit Dashboard: QTBUG-130552 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
599790,2 | QNetworkConnectionMonitor[Mac]: Fix potential use-after/during-free | dev | qt/qtbase | Status: ABANDONED | 0 | 0 |
601950,4 | QNetworkConnectionMonitor[Mac]: Fix potential use-after/during-free | dev | qt/qtbase | Status: MERGED | +2 | 0 |
605024,2 | QNetworkConnectionMonitor[Mac]: Fix potential use-after/during-free | 6.8 | qt/qtbase | Status: MERGED | +2 | 0 |
605485,2 | QNetworkConnectionMonitor[Mac]: Fix potential use-after/during-free | tqtc/lts-6.5 | qt/tqtc-qtbase | Status: MERGED | +2 | 0 |