]> git.cworth.org Git - apitrace/commitdiff
Prevent segfault on glretrace crash (fixes issue #52).
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Thu, 24 Nov 2011 16:30:49 +0000 (16:30 +0000)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Thu, 24 Nov 2011 16:30:49 +0000 (16:30 +0000)
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.

gui/retracer.cpp
gui/retracer.h

index eaa86e33ef4844363994a2e41886dbf36c8c3097..073361718c82bd7f88eca2f5a99b3a9dd4d3e5f7 100644 (file)
@@ -141,7 +141,7 @@ void RetraceProcess::start()
 }
 
 
-void RetraceProcess::replayFinished()
+void RetraceProcess::replayFinished(int exitCode, QProcess::ExitStatus exitStatus)
 {
     QByteArray output = m_process->readAllStandardOutput();
     QString msg;
@@ -152,14 +152,21 @@ void RetraceProcess::replayFinished()
     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");
     } else {
-        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');
@@ -182,9 +189,16 @@ void RetraceProcess::replayFinished()
 
 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();
+#endif
 
     emit error(
         tr("Couldn't execute the replay file '%1'").arg(m_fileName));
@@ -200,7 +214,7 @@ RetraceProcess::RetraceProcess(QObject *parent)
     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)));
 }
index 4a43c261d7ec10ad1442b909e7414aa63866dd2b..127c9ab55cb9d414c760c4bf274821ded899ec3c 100644 (file)
@@ -48,7 +48,7 @@ signals:
     void retraceErrors(const QList<ApiTraceError> &errors);
 
 private slots:
-    void replayFinished();
+    void replayFinished(int exitCode, QProcess::ExitStatus exitStatus);
     void replayError(QProcess::ProcessError err);
 
 private: