Create QApplication in main thread but be warned create not on main thread
-
Hi, I'm using qt6.4.3 on window to develop a communication program. Recently, some users report their program does not work (mostly happen when computer open and set the program autorun). After debug with dmp and log, I found I got this warnning in my log.
qWarning(): WARNING: QApplication was not created in the main() thread.
But I actually create QApplication in main function in main thread. After researching the information in document, I know there maybe some work in other thread create qobject befroe I create QApplication, so I change the order of my code, I put the code create QApplication at the first line in main function, but the problem still exist.
QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv) { ... QThread *cur = QThread::currentThread(); // note: this may end up setting theMainThread! if (cur != theMainThread.loadAcquire()) qWarning("WARNING: QApplication was not created in the main() thread."); #endif }
After read the source code, I known this warnning comes from QCoreApplicationPrivate constructor when the static variable theMainThread is not equal to current thead. Any other Object create in other thread will init the theMainThread, then create the QApplication will get the warnning.
So I add a messagebox in qt source code, like follow
file: qthread_win.cpp QThreadData *QThreadData::current(bool createIfNecessary) { ... if (!QCoreApplicationPrivate::theMainThread) { QCoreApplicationPrivate::theMainThread = threadData->thread.loadRelaxed(); ::MessageBox(NULL, L"Init theMainThread!", L"Init theMainThread!", MB_OK); } ... } and file: qthread.cpp QThreadData *QThreadData::current(bool createIfNecessary) { ... if (!QCoreApplicationPrivate::theMainThread.loadAcquire()) { QCoreApplicationPrivate::theMainThread.storeRelease(data->thread.loadRelaxed()); ::MessageBox(NULL, L"Init theMainThread!", L"Init theMainThread!", MB_OK); } ... }
Then I send the new Qt6Core.dll to my user and create dump when messagebox was showed. Then I found something, the WenEngineCore.dll is init on other thread before main thread. And it will create QFile object to read qtlogging.ini, because QFile is a subclass of QObject, so theMainThread will be inited.
main thread here > ntdll.dll!NtWaitForSingleObject() 未知 非用户代码。已加载符号。 ntdll.dll!_LdrpInitialize() 未知 非用户代码。已加载符号。 ntdll.dll!LdrpInitialize() 未知 非用户代码。已加载符号。 ntdll.dll!LdrInitializeThunk() 未知 非用户代码。已加载符号。
not main thread win32u.dll!00007ffa066711c4() 未知 非用户代码。包含/排除设置已禁用符号加载。 user32.dll!DialogBox2() 未知 非用户代码。已加载符号。 user32.dll!InternalDialogBox() 未知 非用户代码。已加载符号。 user32.dll!SoftModalMessageBox() 未知 非用户代码。已加载符号。 user32.dll!MessageBoxWorker(struct _MSGBOXDATA *) 未知 非用户代码。已加载符号。 user32.dll!MessageBoxTimeoutW() 未知 非用户代码。已加载符号。 user32.dll!MessageBoxW() 未知 非用户代码。已加载符号。 Qt6Core.dll!QThreadData::current(bool createIfNecessary) 行 95 C++ 已加载符号。 Qt6Core.dll!QObject::QObject(QObjectPrivate & dd, QObject * parent=0x0000000000000000) 行 912 C++ 已加载符号。 Qt6Core.dll!QIODevice::QIODevice(QIODevicePrivate & dd, QObject * parent) 行 457 C++ 已加载符号。 Qt6Core.dll!QFileDevice::QFileDevice(QFileDevicePrivate & dd, QObject * parent) 行 186 C++ 已加载符号。 Qt6Core.dll!QFile::QFile(const QString & name={...}) 行 234 C++ 已加载符号。 Qt6Core.dll!loadRulesFromFile(const QString & filePath) 行 253 C++ 已加载符号。 Qt6Core.dll!QLoggingRegistry::initializeRules() 行 294 C++ 已加载符号。 [内联框架] Qt6Core.dll!QLoggingRegistry::{ctor}() 行 242 C++ 已加载符号。 [内联框架] Qt6Core.dll!`anonymous-namespace'::Q_QGS_qtLoggingRegistry::innerFunction(void *) 行 29 C++ 已加载符号。 [内联框架] Qt6Core.dll!QtGlobalStatic::Holder<`anonymous namespace'::Q_QGS_qtLoggingRegistry>::{ctor}() 行 37 C++ 已加载符号。 [内联框架] Qt6Core.dll!QGlobalStatic<QtGlobalStatic::Holder<`anonymous namespace'::Q_QGS_qtLoggingRegistry>>::instance() 行 91 C++ 已加载符号。 [内联框架] Qt6Core.dll!QGlobalStatic<QtGlobalStatic::Holder<`anonymous namespace'::Q_QGS_qtLoggingRegistry>>::operator()() 行 73 C++ 已加载符号。 Qt6Core.dll!QLoggingRegistry::instance() 行 410 C++ 已加载符号。 [内联框架] Qt6Core.dll!QLoggingCategory::init(const char *) 行 184 C++ 已加载符号。 Qt6Core.dll!QLoggingCategory::QLoggingCategory(const char * category, QtMsgType enableForLevel=QtDebugMsg) 行 172 C++ 已加载符号。 Qt6Quick.dll!QSG_LOG_INFO() 行 44 C++ 已加载符号。 [内联框架] Qt6Quick.dll!`anonymous-namespace'::QLoggingCategoryMacroHolder<0>::{ctor}(const QLoggingCategory &(*)()) 行 73 C++ 已加载符号。 Qt6Quick.dll!QSGRhiSupport::applySettings() 行 146 C++ 已加载符号。 ucrtbase.dll!00007ffa0658e473() 未知 非用户代码。包含/排除设置已禁用符号加载。 Qt6WebEngineCore.dll!dllmain_crt_process_attach(HINSTANCE__ * const instance=0x00007ff94bac0000, void * const reserved=0x0000006f7bcff7d0) 行 66 C++ 非用户代码。已加载符号。 > Qt6WebEngineCore.dll!dllmain_dispatch(HINSTANCE__ * const instance=0x00007ff94bac0000, const unsigned long reason=1, void * const reserved=0x0000006f7bcff7d0) 行 276 C++ 非用户代码。已加载符号。 ntdll.dll!LdrpCallInitRoutine() 未知 非用户代码。已加载符号。 ntdll.dll!LdrpInitializeNode() 未知 非用户代码。已加载符号。 ntdll.dll!LdrpInitializeGraphRecurse() 未知 非用户代码。已加载符号。 ntdll.dll!LdrpInitializeGraphRecurse() 未知 非用户代码。已加载符号。 ntdll.dll!LdrpInitializeGraphRecurse() 未知 非用户代码。已加载符号。 ntdll.dll!LdrpInitializeGraphRecurse() 未知 非用户代码。已加载符号。 ntdll.dll!LdrpInitializeGraphRecurse() 未知 非用户代码。已加载符号。 ntdll.dll!LdrpInitializeProcess() 未知 非用户代码。已加载符号。 ntdll.dll!_LdrpInitialize() 未知 非用户代码。已加载符号。 ntdll.dll!LdrpInitialize() 未知 非用户代码。已加载符号。 ntdll.dll!LdrInitializeThunk() 未知 非用户代码。已加载符号。
To solve this probleam, I finally import the private header file (private/qcoreapplication_p.h) and reset the static variable theMainThread in main function and then my program work.
So I'm curious if this is a bug?
-
First upgrade to a recent version. If the error still persists, create a minimal, compilable example. And if it then still exists it might be a bug in Qt not yet fixed.