crash at GetExitCodeProcess in qprocess_win.cpp



  • Hi,
    I see this crash from my customer's Windows. Can anyone tell what is reason for GetExitCodeProcess that leads Qt crash?
    In my application, I create a process to run an .exe file. I use Qt 5.13.
    Windows version: 10.0.17134.1, 64 bit.

    STACK_TEXT:  
    0000009a`e61fc4f0 00007ff8`1d9a7cce : 00007ff8`1d850000 00007ff8`1d850000 00000220`392f3a60 0000009a`e61fc710 : Qt5Core!QProcessPrivate::findExitCode+0x15
    0000009a`e61fc520 00007ff8`1da3bc03 : 00000000`00000000 00007ff8`1ddede20 0000009a`e61fc699 00007ff8`1ddede20 : Qt5Core!QProcess::qt_static_metacall+0x1be
    0000009a`e61fc5c0 00007ff8`1dad7389 : 00000220`397c3950 00000220`00000003 00000220`397c3950 00000000`00000000 : Qt5Core!QMetaObject::activate+0x5a3
    0000009a`e61fc6e0 00007ff8`1da61080 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : Qt5Core!QWinEventNotifier::activated+0x49
    0000009a`e61fc740 00007ff8`1da1b127 : 00000220`38db7010 00000000`00000001 00000220`38db7010 00000220`397c3950 : Qt5Core!QWinEventNotifier::event+0x180
    0000009a`e61fc8a0 00007ff8`1da1b1e9 : 00000000`00000000 0000009a`e61fc998 ffffffff`ffffffff 00000220`397c3950 : Qt5Core!QCoreApplication::notify+0x67
    0000009a`e61fc8f0 00007ff8`1da633f9 : 0000009a`e61fca00 00007ff8`7fe6031d 00000000`00000000 00000220`397c3d50 : Qt5Core!QCoreApplication::notifyInternal2+0xb9
    0000009a`e61fc970 00007ff8`1da64d19 : 00000000`00000000 0000009a`e61fcac0 00000220`3937c601 00000000`00000024 : Qt5Core!QEventDispatcherWin32::activateEventNotifiers+0xa9
    0000009a`e61fc9c0 00007ff8`1da1772b : 00000220`397c3d50 00000000`00000000 00000220`3944b700 00000000`00000000 : Qt5Core!QEventDispatcherWin32::processEvents+0x649
    0000009a`e61ffb30 00007ff8`1d876742 : 00000220`395c49c0 00000220`395c49c0 00000220`397c3cf0 00000220`395c4950 : Qt5Core!QEventLoop::exec+0x1eb
    0000009a`e61ffbb0 00007ff8`1d879009 : 00000220`395c49c0 00000220`395c49c0 00000220`395c4950 00000220`395c49c0 : Qt5Core!QThread::exec+0x92
    0000009a`e61ffc00 00007ff8`80864034 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : Qt5Core!QThreadPrivate::start+0x189
    0000009a`e61ffc40 00007ff8`82713691 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0x14
    0000009a`e61ffc70 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21
    
    
    FAULTING_SOURCE_LINE:  c:\users\qt\work\qt\qtbase\src\corelib\io\qprocess_win.cpp
    
    FAULTING_SOURCE_FILE:  c:\users\qt\work\qt\qtbase\src\corelib\io\qprocess_win.cpp
    
    FAULTING_SOURCE_LINE_NUMBER:  827
    
    FAULTING_SOURCE_CODE:  
       823: void QProcessPrivate::findExitCode()
       824: {
       825:     DWORD theExitCode;
       826:     Q_ASSERT(pid);
    >  827:     if (GetExitCodeProcess(pid->hProcess, &theExitCode)) {
       828:         exitCode = theExitCode;
       829:         crashed = (exitCode == 0xf291   // our magic number, see killProcess
       830:                    || (theExitCode >= 0x80000000 && theExitCode < 0xD0000000));
       831:     }
       832: }
    

    Thanks!


  • Lifetime Qt Champion

    Hi,

    Can you explain what your program is doing ?



  • Here is the code:
    QtOSQuery.h

    class QtOSQuery : public QObject
    {
        Q_OBJECT
    private:
        QProcess process;
    public:
        explicit QtOSQuery(QObject *parent = nullptr);
        ~QtOSQuery();
        void callQuery(const QString& query,bool isAsync);
        void setProgram(const QString &programPath);
    signals:
        void queryResult(const QJsonArray &value);
        void queryFinished();
        void queryError();
    public slots:
        void onReadyReadStandardOutput();
    };
    

    QtOSQuery.cpp

    QtOSQuery::QtOSQuery(QObject *parent) : QObject(parent)
    {
        connect(&process,&QProcess::readyReadStandardOutput,this,&QtOSQuery::onReadyReadStandardOutput);
        connect(&process,QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),this,[this](int exitCode, QProcess::ExitStatus exitStatus)
        {
            qDebug() << "os query finish with code " << exitCode << " status " << exitStatus;
            emit queryFinished();
        });
        connect(&process,&QProcess::errorOccurred,this,[this](QProcess::ProcessError error)
        {
            qDebug() << "os query error " << error;
            emit queryError();
        });
    }
    
    QtOSQuery::~QtOSQuery()
    {
        qDebug() << "Call destructor QtOSQuery";
        if(process.isOpen())
            process.close();
    }
    
    void QtOSQuery::setProgram(const QString &programPath)
    {
        process.setProgram(programPath);
    }
    
    void QtOSQuery::callQuery(const QString &query, bool isAsync)
    {
        QStringList args;
        args << query;
        process.setArguments(args);
        process.open();
        if(!isAsync)
            process.waitForReadyRead();
    }
    
    void QtOSQuery::onReadyReadStandardOutput()
    {
        QJsonDocument doc = QJsonDocument::fromJson(process.readAll());
        // output should always is json array
        Q_ASSERT(doc.isArray());
        emit(queryResult(doc.array()));
        process.terminate();
        QThread::msleep(100);
        process.close();
        if (process.state() != QProcess::NotRunning)
        {
            process.kill();
            QThread::msleep(100);
        }
    }
    

    Code where QtOSQuery is inited:

    void CortexUtilGetOSInfo::getOSUserInfoFromConnectionPort(quint32 port)
    {
        auto query = new QtOSQuery;
        query->setProgram(executableFilePath);
    
        connect(query,&QtOSQuery::queryResult,this,&CortexUtilGetOSInfo::getUserInfoSuccess);
        connect(query,&QtOSQuery::queryFinished,query,&QtOSQuery::deleteLater);
    
        // handle QProcess error
        connect(query,&QtOSQuery::queryError,query,&QtOSQuery::deleteLater);
    
        query->callQuery(QString(queryStr, true);
    
        // want to delete this query when this thread has 
        connect(QThread::currentThread(),&QThread::finished,query,&QObject::deleteLater);
    }
    

    Can you take a look @SGaist ?



  • @thamht4190
    I would have thought the most likely reason for the "crash" is that pid->hProcess is "not valid" at the instant GetExitCodeProcess() is called.

    Again, only a guess, but: in your onReadyReadStandardOutput() you terminate the process. Bearing in mind that is a slot called while the process is still very much active, I wonder what state things might be in internally when that returns. I would start by commenting out your "process termination" stuff and see where that gets you?



  • Thanks @JonB . The problem seems gone when I remove these "process terminate" code.


Log in to reply