Unsolved New QCoreApplication crash in non Qt environment
-
Hi,
I'm using a library written with Qt framework within Matlab. Simple task, I have created a mex file, actual DLL with a single entry point, from which I load my library and issue the calls.
I need a QCoreApplication instance in order to have an event loop. So in my code I test QCoreApplication::instance() and if null I create one. When the last library object has been deleted, I delete the QCoreApplication application I have created.
Without unloading the DLL in between, a new library object can be created after QCoreApplication has been deleted. So I test QCoreApplication::instance() and if null I create one. At this point the program crashes.
I traced down the origin of the crash being in C:\Qt\Qt5.6.0-x64\5.6\Src\qtbase\src\corelib\kernel\qcoreapplication.cpp line 2126.
if (d->argc) { static const char *procName = d->argv[0]; if (qstrcmp(procName, d->argv[0]) != 0) { // clear the cache if the procname changes, so we reprocess it. QCoreApplicationPrivate::clearApplicationFilePath(); procName = d->argv[0]; } }
The location of the crash is:
static const char *procName = d->argv[0];
Here is a snippet of my code
QCoreApplication* pQApplication = nullptr; static int argc = 1; static char * argv[] = { "sharedlib.app", 0 }; SI_IMPEXP int SI_Load() { if (!QCoreApplication::instance()) { QCoreApplication::addLibraryPath("C:/Windows/System32/Specim"); pQApplication = new QCoreApplication(argc, argv); } } SI_IMPEXP int SI_Unload() { if (pQApplication) { delete pQApplication; pQApplication = nullptr; } } SI_IMPEXP int SI_Test() { qDebug() << "Test"; }
From reading QCoreApplication source code, I now understand argv cannot change during the process lifetime. So I declared it as a global static member.
I do the following sequence and check the memory location of argv. Here is an example of memory location
SI_Load: argv = 0x000007fee3fd7008 {0x000007fee3fa2c00 "sharedlib.app", 0x0000000000000000 <NULL>}
SI_Test: argv = 0x000007fee3fd7008 {0x000007fee3fa2c00 "sharedlib.app", 0x0000000000000000 <NULL>}
SI_Unload argv = 0x000007fee3fd7008 {0x000007fee3fa2c00 "sharedlib.app", 0x0000000000000000 <NULL>}
SI_Load argv = 0x000007fee3967008 {0x000007fee3932c00 "sharedlib.app", 0x0000000000000000 <NULL>} <-- new argv allocation – QcoreApplication constructor will crash since the already initialized *static const char procName points to old memory.Each of these call are run from the same thread and same process ID. argv is reallocated only after SI_Unload has returned.
I'm puzzled. How could deleting QCoreAppliction instance change a global static variable allocation? I'm I missing something fundamental?
I hope someone can enlighten me.
Thanks.