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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.