From eca1fa3b2fd0a93b01418b462642c5ada6fdb9f0 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 11 Jul 2024 15:52:28 +0200 Subject: [PATCH] Android: Fix a crash on Creator shutdown during app startup The AndroidRunnerWorker lives in a separate thread created by AndroidRunner. Thus, we can't delete it directly from the AndroidRunner's d'tor. Instead, we connect to QThread's finished() signal and delete the worker later. Make m_pidRunner a child of AndroidRunnerWorker so that it's moved together with its parent to the other thread. Change-Id: I5c3723315ee5183fa8451f0706311b14f173dca1 Reviewed-by: Alessandro Portale --- src/plugins/android/androidrunner.cpp | 19 ++++++++++--------- src/plugins/android/androidrunner.h | 2 +- src/plugins/android/androidrunnerworker.cpp | 1 + 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/plugins/android/androidrunner.cpp b/src/plugins/android/androidrunner.cpp index 260bef647f5..904b7c71762 100644 --- a/src/plugins/android/androidrunner.cpp +++ b/src/plugins/android/androidrunner.cpp @@ -54,23 +54,24 @@ AndroidRunner::AndroidRunner(RunControl *runControl, const QString &intentName) const int apiLevel = AndroidManager::deviceApiLevel(m_target); qCDebug(androidRunnerLog) << "Device API:" << apiLevel; - m_worker.reset(new AndroidRunnerWorker(this, m_packageName)); + m_worker = new AndroidRunnerWorker(this, m_packageName); m_worker->setIntentName(intent); m_worker->setIsPreNougat(apiLevel <= 23); m_worker->moveToThread(&m_thread); + QObject::connect(&m_thread, &QThread::finished, m_worker, &QObject::deleteLater); - connect(this, &AndroidRunner::asyncStart, m_worker.data(), &AndroidRunnerWorker::asyncStart); - connect(this, &AndroidRunner::asyncStop, m_worker.data(), &AndroidRunnerWorker::asyncStop); + connect(this, &AndroidRunner::asyncStart, m_worker, &AndroidRunnerWorker::asyncStart); + connect(this, &AndroidRunner::asyncStop, m_worker, &AndroidRunnerWorker::asyncStop); connect(this, &AndroidRunner::androidDeviceInfoChanged, - m_worker.data(), &AndroidRunnerWorker::setAndroidDeviceInfo); - connect(m_worker.data(), &AndroidRunnerWorker::remoteProcessStarted, + m_worker, &AndroidRunnerWorker::setAndroidDeviceInfo); + + connect(m_worker, &AndroidRunnerWorker::remoteProcessStarted, this, &AndroidRunner::handleRemoteProcessStarted); - connect(m_worker.data(), &AndroidRunnerWorker::remoteProcessFinished, + connect(m_worker, &AndroidRunnerWorker::remoteProcessFinished, this, &AndroidRunner::handleRemoteProcessFinished); - connect(m_worker.data(), &AndroidRunnerWorker::remoteOutput, - this, &AndroidRunner::remoteOutput); - connect(m_worker.data(), &AndroidRunnerWorker::remoteErrorOutput, + connect(m_worker, &AndroidRunnerWorker::remoteOutput, this, &AndroidRunner::remoteOutput); + connect(m_worker, &AndroidRunnerWorker::remoteErrorOutput, this, &AndroidRunner::remoteErrorOutput); connect(&m_outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort, diff --git a/src/plugins/android/androidrunner.h b/src/plugins/android/androidrunner.h index 6b15d8fff44..856ad314c1c 100644 --- a/src/plugins/android/androidrunner.h +++ b/src/plugins/android/androidrunner.h @@ -56,7 +56,7 @@ private: QString m_launchedAVDName; QThread m_thread; QTimer m_checkAVDTimer; - QScopedPointer m_worker; + AndroidRunnerWorker *m_worker = nullptr; QPointer m_target; Utils::Port m_debugServerPort; QUrl m_qmlServer; diff --git a/src/plugins/android/androidrunnerworker.cpp b/src/plugins/android/androidrunnerworker.cpp index 9befaba742a..095c6e99e84 100644 --- a/src/plugins/android/androidrunnerworker.cpp +++ b/src/plugins/android/androidrunnerworker.cpp @@ -203,6 +203,7 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa QtSupport::QtVersion *version = QtSupport::QtKitAspect::qtVersion(target->kit()); m_useAppParamsForQmlDebugger = version->qtVersion() >= QVersionNumber(5, 12); + m_pidRunner.setParent(this); // Move m_pidRunner object together with *this into a separate thread. } AndroidRunnerWorker::~AndroidRunnerWorker()