diff --git a/3rdparty/perfparser b/3rdparty/perfparser index ceab7edc3..0a5547f2b 160000 --- a/3rdparty/perfparser +++ b/3rdparty/perfparser @@ -1 +1 @@ -Subproject commit ceab7edc34d70c948a61360feb99b620d7e10f83 +Subproject commit 0a5547f2bd730cd4a1aafe2dc6c944c1f8650318 diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 71ffd1be4..692bb4535 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -125,6 +125,7 @@ MainWindow::MainWindow(QWidget* parent) settings->setKallsyms(m_settingsDialog->kallsyms()); settings->setArch(m_settingsDialog->arch()); settings->setObjdump(m_settingsDialog->objdump()); + settings->setPerfMapPath(m_settingsDialog->perfMapPath()); }); connect(settings, &Settings::sysrootChanged, m_resultsPage, &ResultsPage::setSysroot); diff --git a/src/parsers/perf/perfparser.cpp b/src/parsers/perf/perfparser.cpp index 7b9d3a8b8..f5efdd569 100644 --- a/src/parsers/perf/perfparser.cpp +++ b/src/parsers/perf/perfparser.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -751,6 +752,9 @@ class PerfParserPrivate : public QObject commands.names[threadStart.pid][threadStart.pid] = parentComm; thread->name = parentComm; } + // check if perf-$pid.map file exists + perfMapFileExists |= QFile::exists(QDir::tempPath() + QDir::separator() + + QLatin1String("perf-%1.map").arg(QString::number(thread->pid))); break; } case EventType::ThreadEnd: { @@ -1388,6 +1392,7 @@ class PerfParserPrivate : public QObject qint32 m_schedSwitchCostId = -1; QHash m_lastSampleTimePerCore; Settings::CostAggregation costAggregation; + bool perfMapFileExists = false; // samples recorded without --call-graph have only one frame int m_numSamplesWithMoreThanOneFrame = 0; @@ -1518,6 +1523,10 @@ bool PerfParser::initParserArgs(const QString& path) if (!arch.isEmpty()) { parserArgs += {QStringLiteral("--arch"), arch}; } + const auto perfMapPath = settings->perfMapPath(); + if (!perfMapPath.isEmpty()) { + parserArgs += {QStringLiteral("--perf-map-path"), perfMapPath}; + } return parserArgs; }; @@ -1564,6 +1573,7 @@ void PerfParser::startParseFile(const QString& path) emit eventsAvailable(d.eventResult); emit frequencyDataAvailable(d.frequencyResult); emit threadNamesAvailable(d.commands); + emit perfMapFileExists(d.perfMapFileExists); if (d.m_numSamplesWithMoreThanOneFrame == 0) { emit parserWarning(tr("Samples contained no call stack frames. Consider passing --call-graph " diff --git a/src/parsers/perf/perfparser.h b/src/parsers/perf/perfparser.h index cd49bd606..21ef39053 100644 --- a/src/parsers/perf/perfparser.h +++ b/src/parsers/perf/perfparser.h @@ -65,6 +65,7 @@ class PerfParser : public QObject void progress(float progress); void debugInfoDownloadProgress(const QString& module, const QString& url, qint64 numerator, qint64 denominator); void stopRequested(); + void perfMapFileExists(bool exists); void parserWarning(const QString& errorMessage); void exportFinished(const QUrl& url); diff --git a/src/resultspage.cpp b/src/resultspage.cpp index a3dc53bff..b76e88a3b 100644 --- a/src/resultspage.cpp +++ b/src/resultspage.cpp @@ -179,6 +179,14 @@ ResultsPage::ResultsPage(PerfParser* parser, QWidget* parent) m_filterBusyIndicator->setVisible(false); }); + connect(parser, &PerfParser::perfMapFileExists, this, [errorWidget = ui->errorWidget](bool exists) { + if (exists) { + errorWidget->setText(tr("Perf Map file detected. Consider exporting in the perfparser format or copying " + "it to another location to keep all backtraces")); + errorWidget->show(); + } + }); + { // create a busy indicator m_filterBusyIndicator = new QWidget(this); diff --git a/src/settings.cpp b/src/settings.cpp index 9bbb47e63..dc2adcc66 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -115,6 +115,12 @@ void Settings::setObjdump(const QString& objdump) emit objdumpChanged(m_objdump); } +void Settings::setPerfMapPath(const QString& perfMapPath) +{ + m_perfMapPath = perfMapPath; + emit perfMapPathChanged(m_perfMapPath); +} + void Settings::setCallgraphParentDepth(int parent) { if (m_callgraphParentDepth != parent) { @@ -221,6 +227,7 @@ void Settings::loadFromFile() setKallsyms(currentConfig.readEntry("kallsyms", "")); setArch(currentConfig.readEntry("arch", "")); setObjdump(currentConfig.readEntry("objdump", "")); + setPerfMapPath(currentConfig.readEntry("perfMapPath", "")); } setPerfPath(sharedConfig->group("Perf").readEntry("path", "")); diff --git a/src/settings.h b/src/settings.h index 9021cd14c..065a7fa7a 100644 --- a/src/settings.h +++ b/src/settings.h @@ -109,6 +109,11 @@ class Settings : public QObject return m_objdump; } + QString perfMapPath() const + { + return m_perfMapPath; + } + int callgraphParentDepth() const { return m_callgraphParentDepth; @@ -166,6 +171,7 @@ class Settings : public QObject void appPathChanged(const QString& path); void archChanged(const QString& arch); void objdumpChanged(const QString& objdump); + void perfMapPathChanged(const QString& perfMapPath); void callgraphChanged(); void lastUsedEnvironmentChanged(const QString& envName); void sourceCodePathsChanged(const QString& paths); @@ -185,6 +191,7 @@ public slots: void setAppPath(const QString& path); void setArch(const QString& arch); void setObjdump(const QString& objdump); + void setPerfMapPath(const QString& perfMapPath); void setCallgraphParentDepth(int parent); void setCallgraphChildDepth(int child); void setCallgraphColors(const QColor& active, const QColor& inactive); @@ -214,6 +221,7 @@ public slots: QString m_arch; QString m_objdump; QString m_sourceCodePaths; + QString m_perfMapPath; QString m_lastUsedEnvironment; diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 426cb41e2..ac2baec53 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -151,6 +151,11 @@ QString SettingsDialog::objdump() const return unwindPage->lineEditObjdump->text(); } +QString SettingsDialog::perfMapPath() const +{ + return unwindPage->lineEditPerfMapPath->text(); +} + void SettingsDialog::addPerfSettingsPage() { auto page = new QWidget(this); diff --git a/src/settingsdialog.h b/src/settingsdialog.h index 36ad2a22f..eaa274f6c 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -40,6 +40,7 @@ class SettingsDialog : public KPageDialog QString kallsyms() const; QString arch() const; QString objdump() const; + QString perfMapPath() const; void keyPressEvent(QKeyEvent* event) override; diff --git a/src/unwindsettingspage.ui b/src/unwindsettingspage.ui index 9e0a4d862..5c0441357 100644 --- a/src/unwindsettingspage.ui +++ b/src/unwindsettingspage.ui @@ -6,7 +6,7 @@ 0 0 - 505 + 556 656 @@ -198,6 +198,20 @@ + + + + Custom perf-$pid.map directory: + + + + + + + KFile::Directory|KFile::ExistingOnly|KFile::LocalOnly + + +