diff options
author | Milian Wolff <milian.wolff@kdab.com> | 2017-03-28 18:16:20 +0200 |
---|---|---|
committer | Milian Wolff <milian.wolff@kdab.com> | 2017-03-29 14:54:07 +0000 |
commit | 8e8c40d7a21bd52f8ee8c71d3c8628fba53efcc2 (patch) | |
tree | 071d52c874ae22a7da24bacec7436932aa4ccfcb | |
parent | 79ae8427155c6124fc23a9ab0bbed0a5ce1ec457 (diff) |
Make maximum number of frames configurable via a CLI argument
The default stays at 64, but it is now possible to unwind more
frames if desired.
Change-Id: I8da2ea340bf97678b2bbbd495b4864da0cf0fddc
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r-- | app/main.cpp | 18 | ||||
-rw-r--r-- | app/perfunwind.cpp | 6 | ||||
-rw-r--r-- | app/perfunwind.h | 7 |
3 files changed, 25 insertions, 6 deletions
diff --git a/app/main.cpp b/app/main.cpp index 41be9ab..fee9055 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -168,6 +168,15 @@ int main(int argc, char *argv[]) QLatin1String("buffer-size"), QLatin1String("10240")); parser.addOption(bufferSize); + QCommandLineOption maxFrames(QLatin1String("max-frames"), + QCoreApplication::translate( + "main", "Maximum number of frames that will be unwound." + " Set the value to -1 to unwind as many frames as possible." + " Beware that this can then potentially lead to infinite loops " + " when the stack got corrupted. Default value is 64."), + QLatin1String("max-frames"), QLatin1String("64")); + parser.addOption(maxFrames); + parser.process(app); QScopedPointer<QFile> outfile; @@ -203,12 +212,19 @@ int main(int argc, char *argv[]) return InvalidOption; } + int maxFramesValue = parser.value(maxFrames).toInt(&ok); + if (!ok) { + qWarning() << "Failed to parse max-frames argument. Expected integer, got:" + << parser.value(maxFrames); + return InvalidOption; + } + PerfUnwind unwind(outfile.data(), parser.value(sysroot), parser.isSet(debug) ? parser.value(debug) : parser.value(sysroot) + parser.value(debug), parser.value(extra), parser.value(appPath), parser.isSet(kallsymsPath) ? parser.value(kallsymsPath) : parser.value(sysroot) + parser.value(kallsymsPath), - parser.isSet(printStats), maxEventBufferSize); + parser.isSet(printStats), maxEventBufferSize, maxFramesValue); PerfHeader header(infile.data()); PerfAttributes attributes; diff --git a/app/perfunwind.cpp b/app/perfunwind.cpp index 5975968..37e418c 100644 --- a/app/perfunwind.cpp +++ b/app/perfunwind.cpp @@ -76,13 +76,15 @@ void PerfUnwind::Stats::finishedRound() PerfUnwind::PerfUnwind(QIODevice *output, const QString &systemRoot, const QString &debugPath, const QString &extraLibsPath, const QString &appPath, - const QString &kallsymsPath, bool printStats, uint maxEventBufferSize) : + const QString &kallsymsPath, bool printStats, uint maxEventBufferSize, + int maxFrames) : m_output(output), m_architecture(PerfRegisterInfo::ARCH_INVALID), m_systemRoot(systemRoot), m_extraLibsPath(extraLibsPath), m_appPath(appPath), m_debugPath(debugPath), m_kallsyms(kallsymsPath), m_maxEventBufferSize(maxEventBufferSize), m_eventBufferSize(0), m_lastFlushMaxTime(0) { m_stats.enabled = printStats; m_currentUnwind.unwind = this; + m_currentUnwind.maxFrames = maxFrames; m_offlineCallbacks.find_elf = dwfl_build_id_find_elf; m_offlineCallbacks.find_debuginfo = dwfl_standard_find_debuginfo; m_offlineCallbacks.section_address = dwfl_offline_section_address; @@ -288,7 +290,7 @@ static int frameCallback(Dwfl_Frame *state, void *arg) bool isactivation; if (!dwfl_frame_pc(state, &pc, &isactivation) - || ui->frames.length() > PerfUnwind::s_maxFrames + || (ui->maxFrames != -1 && ui->frames.length() > ui->maxFrames) || pc == 0) { ui->firstGuessedFrame = ui->frames.length(); qWarning() << dwfl_errmsg(dwfl_errno()) << ui->firstGuessedFrame; diff --git a/app/perfunwind.h b/app/perfunwind.h index c80fb47..ffff2f2 100644 --- a/app/perfunwind.h +++ b/app/perfunwind.h @@ -89,23 +89,24 @@ public: }; struct UnwindInfo { - UnwindInfo() : frames(0), unwind(0), sample(0), + UnwindInfo() : frames(0), unwind(0), sample(0), maxFrames(64), firstGuessedFrame(-1), isInterworking(false) {} QHash<quint32, QHash<quint64, Dwarf_Word>> stackValues; QVector<qint32> frames; PerfUnwind *unwind; const PerfRecordSample *sample; + int maxFrames; int firstGuessedFrame; bool isInterworking; }; static const quint32 s_kernelPid = std::numeric_limits<quint32>::max(); - static const int s_maxFrames = 64; PerfUnwind(QIODevice *output, const QString &systemRoot, const QString &debugInfo, const QString &extraLibs, const QString &appPath, - const QString &kallsymsPath, bool printStats, uint maxEventBufferSize); + const QString &kallsymsPath, bool printStats, uint maxEventBufferSize, + int maxFrames); ~PerfUnwind(); PerfRegisterInfo::Architecture architecture() const { return m_architecture; } |