summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2017-09-13 14:47:02 +0200
committerUlf Hermann <ulf.hermann@qt.io>2017-09-29 08:27:04 +0000
commit5499916b0d2af6a54bab04732bed9bc6e7129522 (patch)
tree44e9d773b1e2bd619e151236cd72f1e0cb6d04ae
parent90563be14aee069603aca87c1f926a692460b6fd (diff)
Prepare PerfUnwind for easier testing
Expose the Stats struct, so that we can verify what it did, reduce the constructor and add default values for most arguments, and allow the event buffer to be manually flushed. Change-Id: I3a9d9028e1316a962885c20e5e624057afac5697 Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
-rw-r--r--app/main.cpp20
-rw-r--r--app/perfunwind.cpp21
-rw-r--r--app/perfunwind.h104
3 files changed, 87 insertions, 58 deletions
diff --git a/app/main.cpp b/app/main.cpp
index bcc2ad8..0de996d 100644
--- a/app/main.cpp
+++ b/app/main.cpp
@@ -111,8 +111,7 @@ int main(int argc, char *argv[])
QDir::rootPath());
parser.addOption(sysroot);
- const auto defaultDebug = QString::fromLatin1("%1usr%1lib%1debug%2%3%1.debug%2.debug")
- .arg(QDir::separator(), QDir::listSeparator(), QDir::homePath());
+ const auto defaultDebug = PerfUnwind::defaultDebugInfoPath();
QCommandLineOption debug(QLatin1String("debug"),
QCoreApplication::translate(
"main",
@@ -150,7 +149,7 @@ int main(int argc, char *argv[])
defaultArch);
parser.addOption(arch);
- const auto defaultKallsyms = QString::fromLatin1("%1proc%1kallsyms").arg(QDir::separator());
+ const auto defaultKallsyms = PerfUnwind::defaultKallsymsPath();
QCommandLineOption kallsymsPath(QLatin1String("kallsyms"),
QCoreApplication::translate(
"main", "Path to kallsyms mapping to resolve kernel "
@@ -227,11 +226,16 @@ int main(int argc, char *argv[])
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(kallsymsPath), parser.isSet(printStats),
- maxEventBufferSize, maxFramesValue);
+ parser.value(extra), parser.value(appPath), parser.isSet(printStats));
+
+ unwind.setKallsymsPath(parser.isSet(kallsymsPath)
+ ? parser.value(kallsymsPath)
+ : (parser.value(sysroot) + parser.value(kallsymsPath)));
+
+ unwind.setIgnoreKallsymsBuildId(parser.isSet(kallsymsPath));
+
+ unwind.setMaxEventBufferSize(maxEventBufferSize);
+ unwind.setMaxUnwindFrames(maxFramesValue);
PerfHeader header(infile.data());
PerfAttributes attributes;
diff --git a/app/perfunwind.cpp b/app/perfunwind.cpp
index 4ace26b..eaad741 100644
--- a/app/perfunwind.cpp
+++ b/app/perfunwind.cpp
@@ -85,19 +85,26 @@ static int find_debuginfo(Dwfl_Module *module, void **userData, const char *modu
return symbolTable->findDebugInfo(module, moduleName, base, file, debugLink, crc, debugInfoFilename);
}
+QString PerfUnwind::defaultDebugInfoPath()
+{
+ return QString::fromLatin1("%1usr%1lib%1debug%2%3%1.debug%2.debug")
+ .arg(QDir::separator(), QDir::listSeparator(), QDir::homePath());
+}
+
+QString PerfUnwind::defaultKallsymsPath()
+{
+ return QString::fromLatin1("%1proc%1kallsyms").arg(QDir::separator());
+}
+
PerfUnwind::PerfUnwind(QIODevice *output, const QString &systemRoot, const QString &debugPath,
- const QString &extraLibsPath, const QString &appPath,
- const QString &kallsymsPath, bool ignoreKallsymsBuildId,
- bool printStats, uint maxEventBufferSize, int maxFrames) :
+ const QString &extraLibsPath, const QString &appPath, bool printStats) :
m_output(output), m_architecture(PerfRegisterInfo::ARCH_INVALID), m_systemRoot(systemRoot),
m_extraLibsPath(extraLibsPath), m_appPath(appPath), m_debugPath(debugPath),
- m_kallsymsPath(kallsymsPath), m_ignoreKallsymsBuildId(ignoreKallsymsBuildId),
- m_maxEventBufferSize(maxEventBufferSize), m_eventBufferSize(0),
- m_lastFlushMaxTime(0)
+ m_kallsymsPath(QDir::rootPath() + defaultKallsymsPath()), m_ignoreKallsymsBuildId(false),
+ m_maxEventBufferSize(10 * (1 << 20)), 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 = find_debuginfo;
m_offlineCallbacks.section_address = dwfl_offline_section_address;
diff --git a/app/perfunwind.h b/app/perfunwind.h
index e259676..e1ab885 100644
--- a/app/perfunwind.h
+++ b/app/perfunwind.h
@@ -33,6 +33,7 @@
#include <QIODevice>
#include <QByteArray>
#include <QString>
+#include <QDir>
#include <limits>
@@ -97,15 +98,67 @@ public:
bool isInterworking;
};
+ struct Stats
+ {
+ Stats()
+ : numSamples(0), numMmaps(0), numRounds(0), numBufferFlushes(0),
+ numTimeViolatingSamples(0), numTimeViolatingMmaps(0),
+ numSamplesInRound(0), numMmapsInRound(0),
+ maxSamplesPerRound(0), maxMmapsPerRound(0),
+ maxSamplesPerFlush(0), maxMmapsPerFlush(0),
+ maxBufferSize(0), maxTotalEventSizePerRound(0),
+ maxTime(0), maxTimeBetweenRounds(0), maxReorderTime(0),
+ lastRoundTime(0), totalEventSizePerRound(0),
+ enabled(false)
+ {}
+
+ void addEventTime(quint64 time);
+ void finishedRound();
+
+ quint64 numSamples;
+ quint64 numMmaps;
+ quint64 numRounds;
+ quint64 numBufferFlushes;
+ quint64 numTimeViolatingSamples;
+ quint64 numTimeViolatingMmaps;
+ int numSamplesInRound;
+ int numMmapsInRound;
+ int maxSamplesPerRound;
+ int maxMmapsPerRound;
+ int maxSamplesPerFlush;
+ int maxMmapsPerFlush;
+ uint maxBufferSize;
+ uint maxTotalEventSizePerRound;
+ quint64 maxTime;
+ quint64 maxTimeBetweenRounds;
+ quint64 maxReorderTime;
+ quint64 lastRoundTime;
+ uint totalEventSizePerRound;
+ bool enabled;
+ };
+
static const quint32 s_kernelPid = std::numeric_limits<quint32>::max();
+ static QString defaultDebugInfoPath();
+ static QString defaultKallsymsPath();
- PerfUnwind(QIODevice *output, const QString &systemRoot, const QString &debugInfo,
- const QString &extraLibs, const QString &appPath,
- const QString &kallsymsPath, bool ignoreKallsymsBuildId,
- bool printStats, uint maxEventBufferSize,
- int maxFrames);
+ PerfUnwind(QIODevice *output, const QString &systemRoot = QDir::rootPath(),
+ const QString &debugPath = defaultDebugInfoPath(),
+ const QString &extraLibs = QString(), const QString &appPath = QString(),
+ bool printStats = false);
~PerfUnwind();
+ QString kallsymsPath() const { return m_kallsymsPath; }
+ void setKallsymsPath(const QString &kallsymsPath) { m_kallsymsPath = kallsymsPath; }
+
+ bool ignoreKallsymsBuildId() const { return m_ignoreKallsymsBuildId; }
+ void setIgnoreKallsymsBuildId(bool ignore) { m_ignoreKallsymsBuildId = ignore; }
+
+ uint maxEventBufferSize() const { return m_maxEventBufferSize; }
+ void setMaxEventBufferSize(uint size) { m_maxEventBufferSize = size; }
+
+ int maxUnwindFrames() const { return m_currentUnwind.maxFrames; }
+ void setMaxUnwindFrames(int maxUnwindFrames) { m_currentUnwind.maxFrames = maxUnwindFrames; }
+
PerfRegisterInfo::Architecture architecture() const { return m_architecture; }
void setArchitecture(PerfRegisterInfo::Architecture architecture)
{
@@ -155,6 +208,9 @@ public:
QString extraLibsPath() const { return m_extraLibsPath; }
QString appPath() const { return m_appPath; }
QString debugPath() const { return m_debugPath; }
+ Stats stats() const { return m_stats; }
+
+ void flushEventBuffer() { flushEventBuffer(0); }
private:
@@ -213,44 +269,6 @@ private:
uint m_eventBufferSize;
quint64 m_lastFlushMaxTime;
- struct Stats
- {
- Stats()
- : numSamples(0), numMmaps(0), numRounds(0), numBufferFlushes(0),
- numTimeViolatingSamples(0), numTimeViolatingMmaps(0),
- numSamplesInRound(0), numMmapsInRound(0),
- maxSamplesPerRound(0), maxMmapsPerRound(0),
- maxSamplesPerFlush(0), maxMmapsPerFlush(0),
- maxBufferSize(0), maxTotalEventSizePerRound(0),
- maxTime(0), maxTimeBetweenRounds(0), maxReorderTime(0),
- lastRoundTime(0), totalEventSizePerRound(0),
- enabled(false)
- {}
-
- void addEventTime(quint64 time);
- void finishedRound();
-
- quint64 numSamples;
- quint64 numMmaps;
- quint64 numRounds;
- quint64 numBufferFlushes;
- quint64 numTimeViolatingSamples;
- quint64 numTimeViolatingMmaps;
- int numSamplesInRound;
- int numMmapsInRound;
- int maxSamplesPerRound;
- int maxMmapsPerRound;
- int maxSamplesPerFlush;
- int maxMmapsPerFlush;
- uint maxBufferSize;
- uint maxTotalEventSizePerRound;
- quint64 maxTime;
- quint64 maxTimeBetweenRounds;
- quint64 maxReorderTime;
- quint64 lastRoundTime;
- uint totalEventSizePerRound;
- bool enabled;
- };
Stats m_stats;
void unwindStack(Dwfl *dwfl);