On glretrace crash, both error and finished QProcess events are emitted, by
this order. Members were reset on error, causing null pointer dereference
on replayFinished.
Fix this by handling abnormal termination on replayFinished too.
replayError should probably removed/merged into replayFinished.
-void RetraceProcess::replayFinished()
+void RetraceProcess::replayFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
QByteArray output = m_process->readAllStandardOutput();
QString msg;
{
QByteArray output = m_process->readAllStandardOutput();
QString msg;
qDebug()<<"\terr = "<<errStr;
qDebug()<<"\tout = "<<output;
#endif
qDebug()<<"\terr = "<<errStr;
qDebug()<<"\tout = "<<output;
#endif
- if (m_captureState) {
- bool ok = false;
- QVariantMap parsedJson = m_jsonParser->parse(output, &ok).toMap();
- ApiTraceState *state = new ApiTraceState(parsedJson);
- emit foundState(state);
- msg = tr("State fetched.");
+
+ if (exitStatus != QProcess::NormalExit) {
+ msg = QLatin1String("Process crashed");
+ } else if (exitCode != 0) {
+ msg = QLatin1String("Process exited with non zero exit code");
- msg = QString::fromUtf8(output);
+ if (m_captureState) {
+ bool ok = false;
+ QVariantMap parsedJson = m_jsonParser->parse(output, &ok).toMap();
+ ApiTraceState *state = new ApiTraceState(parsedJson);
+ emit foundState(state);
+ msg = tr("State fetched.");
+ } else {
+ msg = QString::fromUtf8(output);
+ }
}
QStringList errorLines = errStr.split('\n');
}
QStringList errorLines = errStr.split('\n');
void RetraceProcess::replayError(QProcess::ProcessError err)
{
void RetraceProcess::replayError(QProcess::ProcessError err)
{
+ /*
+ * XXX: this function is likely unnecessary and should be eliminated given
+ * that replayFinished is always called, even on errors.
+ */
+
+#if 0
qDebug()<<"Process error = "<<err;
qDebug()<<"\terr = "<<m_process->readAllStandardError();
qDebug()<<"\tout = "<<m_process->readAllStandardOutput();
qDebug()<<"Process error = "<<err;
qDebug()<<"\terr = "<<m_process->readAllStandardError();
qDebug()<<"\tout = "<<m_process->readAllStandardOutput();
emit error(
tr("Couldn't execute the replay file '%1'").arg(m_fileName));
emit error(
tr("Couldn't execute the replay file '%1'").arg(m_fileName));
qRegisterMetaType<QList<ApiTraceError> >();
connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)),
qRegisterMetaType<QList<ApiTraceError> >();
connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)),
- this, SLOT(replayFinished()));
+ this, SLOT(replayFinished(int, QProcess::ExitStatus)));
connect(m_process, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(replayError(QProcess::ProcessError)));
}
connect(m_process, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(replayError(QProcess::ProcessError)));
}
void retraceErrors(const QList<ApiTraceError> &errors);
private slots:
void retraceErrors(const QList<ApiTraceError> &errors);
private slots:
+ void replayFinished(int exitCode, QProcess::ExitStatus exitStatus);
void replayError(QProcess::ProcessError err);
private:
void replayError(QProcess::ProcessError err);
private: