summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilian Wolff <milian.wolff@kdab.com>2017-03-28 18:16:20 +0200
committerMilian Wolff <milian.wolff@kdab.com>2017-03-29 14:54:07 +0000
commit8e8c40d7a21bd52f8ee8c71d3c8628fba53efcc2 (patch)
tree071d52c874ae22a7da24bacec7436932aa4ccfcb
parent79ae8427155c6124fc23a9ab0bbed0a5ce1ec457 (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.cpp18
-rw-r--r--app/perfunwind.cpp6
-rw-r--r--app/perfunwind.h7
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; }