From a20a795cb585b75d4d03d671a9a235ca67d3418d Mon Sep 17 00:00:00 2001 From: Jose Fonseca Date: Tue, 19 Jan 2016 14:16:24 +0000 Subject: gui: Show leaks. Based on comicfans change, but adapted to invoke `apitrace leaks`. Issue #416. v2: Add missing file. --- gui/CMakeLists.txt | 1 + gui/leaktracethread.cpp | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ gui/leaktracethread.h | 35 +++++++++++++++++++++ gui/mainwindow.cpp | 24 +++++++++++++++ gui/mainwindow.h | 2 ++ gui/ui/mainwindow.ui | 9 ++++++ 6 files changed, 153 insertions(+) create mode 100644 gui/leaktracethread.cpp create mode 100644 gui/leaktracethread.h (limited to 'gui') diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index a86336bb..b74e3ece 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -51,6 +51,7 @@ set(qapitrace_SRCS traceprocess.cpp trimprocess.cpp vertexdatainterpreter.cpp + leaktracethread.cpp graphing/frameaxiswidget.cpp graphing/graphwidget.cpp graphing/graphaxiswidget.cpp diff --git a/gui/leaktracethread.cpp b/gui/leaktracethread.cpp new file mode 100644 index 00000000..a5b1e346 --- /dev/null +++ b/gui/leaktracethread.cpp @@ -0,0 +1,82 @@ +#include "leaktracethread.h" + +#include "apitracecall.h" + +#include +#include + +void LeakTraceThread::run() +{ + QString msg = QLatin1String("Replay finished!"); + + /* + * Construct command line + */ + + QString prog = "apitrace"; + QStringList arguments; + arguments << "leaks"; + arguments << filename; + + /* + * Start the process. + */ + + { + QDebug debug(QtDebugMsg); + debug << "Running:"; + debug << prog; + foreach (const QString &argument, arguments) { + debug << argument; + } + } + + QProcess process; + + process.start(prog, arguments, QIODevice::ReadOnly); + if (!process.waitForStarted(-1)) { + return; + } + + /* + * Wait for process termination + */ + + process.waitForFinished(-1); + + if (process.exitStatus() != QProcess::NormalExit) { + msg = QLatin1String("Process crashed"); + } else if (process.exitCode() != 0) { + msg = QLatin1String("Process exited with non zero exit code"); + } + + /* + * Parse errors. + */ + + QList errors; + process.setReadChannel(QProcess::StandardError); + QRegExp regexp("(^\\d+): +(\\b\\w+\\b): ([^\\r\\n]+)[\\r\\n]*$"); + while (!process.atEnd()) { + QString line = process.readLine(); + qDebug() << line; + if (regexp.indexIn(line) != -1) { + qDebug() << "error"; + ApiTraceError error; + error.callIndex = regexp.cap(1).toInt(); + error.type = regexp.cap(2); + error.message = regexp.cap(3); + errors.append(error); + } else { + qDebug() << line; + } + } + + /* + * Emit signals + */ + + error = !errors.empty(); + emit leakTraceErrors(errors); +} + diff --git a/gui/leaktracethread.h b/gui/leaktracethread.h new file mode 100644 index 00000000..cbc16ea0 --- /dev/null +++ b/gui/leaktracethread.h @@ -0,0 +1,35 @@ + +#pragma once + +#include +#include +#include + +struct ApiTraceError; + +class LeakTraceThread: public QThread{ + + Q_OBJECT + + public: + + LeakTraceThread(QString _filename):filename(_filename){} + + + bool hasError()const {return error;} + signals: + + void leakTraceErrors(const QList &errors); + + protected: + + virtual void run(); + + private: + + QString filename; + + bool error=false; +}; + + diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 8bf464a0..129e634d 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -24,6 +24,7 @@ #include "vertexdatainterpreter.h" #include "trace_profiler.hpp" #include "image/image.hpp" +#include "leaktracethread.h" #include #include @@ -864,6 +865,27 @@ void MainWindow::showSettings() dialog.exec(); } +void MainWindow::leakTrace() +{ + LeakTraceThread *t=new LeakTraceThread(m_trace->fileName()); + + connect (t,SIGNAL(finished()),this,SLOT(leakTraceFinished())); + + connect (t,SIGNAL(leakTraceErrors(const QList &)), + this,SLOT(slotRetraceErrors(const QList&))); + + t->start(); +} + +void MainWindow::leakTraceFinished(){ + + LeakTraceThread *t = qobject_cast(sender()); + + m_ui.errorsDock->setVisible(t->hasError()); + + delete t; +} + void MainWindow::openHelp(const QUrl &url) { QDesktopServices::openUrl(url); @@ -1082,6 +1104,8 @@ void MainWindow::initConnections() this, SLOT(showThumbnails())); connect(m_ui.actionOptions, SIGNAL(triggered()), this, SLOT(showSettings())); + connect(m_ui.actionLeakTrace,SIGNAL(triggered()), + this, SLOT(leakTrace())); connect(m_ui.callView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(callItemSelected(const QModelIndex &))); diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 34f4113e..8740ab76 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -72,6 +72,8 @@ private slots: void showThumbnails(); void trim(); void showSettings(); + void leakTrace(); + void leakTraceFinished(); void openHelp(const QUrl &url); void showSurfacesMenu(const QPoint &pos); void showSelectedSurface(); diff --git a/gui/ui/mainwindow.ui b/gui/ui/mainwindow.ui index 41a7d214..376f70e3 100644 --- a/gui/ui/mainwindow.ui +++ b/gui/ui/mainwindow.ui @@ -92,6 +92,7 @@ + @@ -776,6 +777,14 @@ Retrace on Android + + + &LeakTrace + + + trace opengl object leaks + + stateDock vertexDataDock errorsDock -- cgit v1.2.3