QProcess segmentation fault in QThread
-
I'm battling a bug where I sometimes get a segmentation fault on QProcess readyReadStandardOutput()/readyReadStandardError() signals when I run it inside a thread and I'm not sure what I'm doing wrong. Below is a minimal example of the crash in a contrived example:
class Process : public QObject { Q_OBJECT public: Process() = default; ~Process() = default; void start(); }; void Process::start() { QProcess process; connect(&process, &QProcess::readyReadStandardOutput, this, [&]() { QByteArray readStdOut = process.readAllStandardOutput(); }); connect(&process, &QProcess::readyReadStandardError, this,[&]() { QByteArray readStdErr = process.readAllStandardError(); }); QStringList args; args << ("+vm"); args << ("-hFs1"); args << ("file.txt"); process.setProgram("D:\\test\\program.exe"); process.setArguments(args); process.start(); if (!process.waitForStarted(-1)) { Q_ASSERT(false); } if (!process.waitForFinished(-1)) { Q_ASSERT(false); } } int main(int argc, char *argv[]) { QApplication a(argc, argv); QThread* thread = new QThread; Process process; process.moveToThread(thread); thread->start(); process.start(); thread->quit(); thread->wait(); delete thread; MainWindow w; w.show(); return a.exec(); }
Can anyone spot what I'm doing wrong?
Thanks -
I'm battling a bug where I sometimes get a segmentation fault on QProcess readyReadStandardOutput()/readyReadStandardError() signals when I run it inside a thread and I'm not sure what I'm doing wrong. Below is a minimal example of the crash in a contrived example:
class Process : public QObject { Q_OBJECT public: Process() = default; ~Process() = default; void start(); }; void Process::start() { QProcess process; connect(&process, &QProcess::readyReadStandardOutput, this, [&]() { QByteArray readStdOut = process.readAllStandardOutput(); }); connect(&process, &QProcess::readyReadStandardError, this,[&]() { QByteArray readStdErr = process.readAllStandardError(); }); QStringList args; args << ("+vm"); args << ("-hFs1"); args << ("file.txt"); process.setProgram("D:\\test\\program.exe"); process.setArguments(args); process.start(); if (!process.waitForStarted(-1)) { Q_ASSERT(false); } if (!process.waitForFinished(-1)) { Q_ASSERT(false); } } int main(int argc, char *argv[]) { QApplication a(argc, argv); QThread* thread = new QThread; Process process; process.moveToThread(thread); thread->start(); process.start(); thread->quit(); thread->wait(); delete thread; MainWindow w; w.show(); return a.exec(); }
Can anyone spot what I'm doing wrong?
Thanks@E106JZ said in QProcess segmentation fault in QThread:
process.start();
This is wrong - it executes the function in the main thread. You have to use signals and slots to call a function in another thread as clearly described in the documentation to QThread. But why do you need a thread here at all?
-
@E106JZ said in QProcess segmentation fault in QThread:
process.start();
This is wrong - it executes the function in the main thread. You have to use signals and slots to call a function in another thread as clearly described in the documentation to QThread. But why do you need a thread here at all?
@Christian-Ehrlicher Thanks, I didn't realise I was doing that. In my case yes I need a background thread to run this lengthy QProcess so I can update the main thread GUI with the progress.
-
@E106JZ said in QProcess segmentation fault in QThread:
yes I need a background thread to run this lengthy QProcess so I can update the main thread GUI with the progress.
Still no reason for a QThread - QProcess is async.
-
@E106JZ said in QProcess segmentation fault in QThread:
yes I need a background thread to run this lengthy QProcess so I can update the main thread GUI with the progress.
Still no reason for a QThread - QProcess is async.
@Christian-Ehrlicher How so? I create a progress window (a QDialog that calls exec()) and inside it has a worker that calls the QProcess. Without a QThread, the QProcess runs and blocks the dialog from appearing until its finished. Can it be done without a QThread?
-
A QProcess does not block anything - it's async.
-
A QProcess does not block anything - it's async.
@Christian-Ehrlicher But if we call waitForFinished() on it then it will block the current thread I mean.
-
@E106JZ said in QProcess segmentation fault in QThread:
But if we call waitForFinished() on it then it will block the current thread I mean.
Then don't call it - it's not needed.
-
@Christian-Ehrlicher But if we call waitForFinished() on it then it will block the current thread I mean.
@E106JZ said in QProcess segmentation fault in QThread:
But if we call waitForFinished() on it then it will block the current thread I mean.
that's the point, waitforfinished is the synchronous version of QProcess, you want to listen to the finished signal, https://doc.qt.io/qt-5/qprocess.html#finished, which is asynchronous
-
Besides, your QProcess instance destroyed after the start() called...