From 7348975b202bf72343ffc76f56f394645bca3527 Mon Sep 17 00:00:00 2001 From: Lieven Hey Date: Tue, 5 Dec 2023 15:27:46 +0100 Subject: [PATCH 1/4] disable disassembly of inlined functions It is not possible to disassemble a inlined functions. This patch disables the disassembly entry in the context menu for these functions. fixes: #548 --- 3rdparty/perfparser | 2 +- src/models/data.h | 6 ++++-- src/parsers/perf/perfparser.cpp | 11 +++++++---- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/3rdparty/perfparser b/3rdparty/perfparser index ab14b6989..7b686d690 160000 --- a/3rdparty/perfparser +++ b/3rdparty/perfparser @@ -1 +1 @@ -Subproject commit ab14b6989d123af60f4c822e8ece8638945139c6 +Subproject commit 7b686d690f5d9be321eef9084087106690c30dd0 diff --git a/src/models/data.h b/src/models/data.h index cf0d2b295..c00fd7dea 100644 --- a/src/models/data.h +++ b/src/models/data.h @@ -26,7 +26,7 @@ QString prettifySymbol(const QString& symbol); struct Symbol { Symbol(const QString& symbol = {}, quint64 relAddr = 0, quint64 size = 0, const QString& binary = {}, - const QString& path = {}, const QString& actualPath = {}, bool isKernel = false) + const QString& path = {}, const QString& actualPath = {}, bool isKernel = false, bool isInline = false) : symbol(symbol) , prettySymbol(Data::prettifySymbol(symbol)) , relAddr(relAddr) @@ -35,6 +35,7 @@ struct Symbol , path(path) , actualPath(actualPath) , isKernel(isKernel) + , isInline(isInline) { } @@ -53,6 +54,7 @@ struct Symbol // actual file path QString actualPath; bool isKernel = false; + bool isInline = false; bool operator<(const Symbol& rhs) const { @@ -66,7 +68,7 @@ struct Symbol bool canDisassemble() const { - return !symbol.isEmpty() && !path.isEmpty() && relAddr > 0 && size > 0; + return !symbol.isEmpty() && !path.isEmpty() && relAddr > 0 && size > 0 && !isInline; } }; diff --git a/src/parsers/perf/perfparser.cpp b/src/parsers/perf/perfparser.cpp index 1a0ecfb94..eb632f528 100644 --- a/src/parsers/perf/perfparser.cpp +++ b/src/parsers/perf/perfparser.cpp @@ -228,12 +228,13 @@ struct Symbol StringId path; StringId actualPath; bool isKernel = false; + bool isInline = false; }; QDataStream& operator>>(QDataStream& stream, Symbol& symbol) { return stream >> symbol.name >> symbol.binary >> symbol.path >> symbol.isKernel >> symbol.relAddr >> symbol.size - >> symbol.actualPath; + >> symbol.actualPath >> symbol.isInline; } QDebug operator<<(QDebug stream, const Symbol& symbol) @@ -245,7 +246,8 @@ QDebug operator<<(QDebug stream, const Symbol& symbol) << "binary=" << symbol.binary << ", " << "path=" << symbol.path << ", " << "actualPath=" << symbol.actualPath << ", " - << "isKernel=" << symbol.isKernel << "}"; + << "isKernel=" << symbol.isKernel << ", " + << "isInline=" << symbol.isInline << "}"; return stream; } @@ -1017,8 +1019,9 @@ class PerfParserPrivate : public QObject const auto pathString = strings.value(symbol.symbol.path.id); const auto actualPathString = strings.value(symbol.symbol.actualPath.id); const auto isKernel = symbol.symbol.isKernel; - bottomUpResult.symbols[symbol.id] = {symbolString, relAddr, size, binaryString, - pathString, actualPathString, isKernel}; + const auto isInline = symbol.symbol.isInline; + bottomUpResult.symbols[symbol.id] = {symbolString, relAddr, size, binaryString, + pathString, actualPathString, isKernel, isInline}; // Count total and missing symbols per module for error report auto& numSymbols = numSymbolsByModule[symbol.symbol.binary.id]; From 2a051f2bc57da18a592f25c49968cf0e2dd1a50c Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Tue, 2 Jan 2024 14:55:41 +0100 Subject: [PATCH 2/4] Distinguish inline frames in the flamegraph Give them a slightly darker/lighter background color but retain a border with the normal background color. --- src/flamegraph.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/flamegraph.cpp b/src/flamegraph.cpp index 003aa7b9f..3f5641335 100644 --- a/src/flamegraph.cpp +++ b/src/flamegraph.cpp @@ -170,8 +170,29 @@ void FrameGraphicsItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* auto noMatchColor = brush().color(); noMatchColor.setAlpha(50); painter->fillRect(rect(), noMatchColor); - } else { // default, when no search is running, or a sub-item is matched - painter->fillRect(rect(), brush()); + } else { + // default, when no search is running, or a sub-item is matched + auto background = brush(); + + // give inline frames a slightly different background color + if (m_symbol.isInline) { + auto color = background.color(); + if (qGray(pen().color().rgb()) < 128) { + color = color.lighter(); + } else { + color = color.darker(); + } + background.setColor(color); + } + painter->fillRect(rect(), background); + + // give inline frames a border with the normal background color + if (m_symbol.isInline) { + const auto oldPen = painter->pen(); + painter->setPen(QPen(brush().color(), 0.)); + painter->drawRect(rect().adjusted(-1, -1, -1, -1)); + painter->setPen(oldPen); + } } const QPen oldPen = painter->pen(); From aebc59fe678242a73d11cb315adf534b1c04bbe7 Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Tue, 2 Jan 2024 15:09:33 +0100 Subject: [PATCH 3/4] Show whether a frame was inlined in tooltips too --- src/flamegraph.cpp | 2 +- src/util.cpp | 11 ++++++++++- src/util.h | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/flamegraph.cpp b/src/flamegraph.cpp index 3f5641335..898af8b4b 100644 --- a/src/flamegraph.cpp +++ b/src/flamegraph.cpp @@ -261,7 +261,7 @@ QString FrameGraphicsItem::description() const root = static_cast(item); } - auto symbol = Util::formatSymbol(m_symbol); + auto symbol = Util::formatSymbolExtended(m_symbol); if (root == this) { return symbol; } diff --git a/src/util.cpp b/src/util.cpp index 2443722e9..492a6a1da 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -91,7 +91,7 @@ std::pair elideArguments(const QString& symbolText) QString formatForTooltip(const Data::Symbol& symbol) { return QCoreApplication::translate("Util", "symbol: %1
binary: %2") - .arg(Util::formatSymbol(symbol).toHtmlEscaped(), Util::formatString(symbol.binary)); + .arg(Util::formatSymbolExtended(symbol).toHtmlEscaped(), Util::formatString(symbol.binary)); } QString formatTooltipImpl(int id, const QString& text, const Data::Costs* selfCosts, const Data::Costs* inclusiveCosts) @@ -266,6 +266,15 @@ QString Util::formatSymbol(const Data::Symbol& symbol, bool replaceEmptyString) return formatString(symbolString, replaceEmptyString); } +QString Util::formatSymbolExtended(const Data::Symbol& symbol) +{ + auto ret = formatSymbol(symbol); + if (symbol.isInline) { + ret = QCoreApplication::translate("Util", "%1 (inlined)").arg(ret); + } + return ret; +} + QString Util::formatCost(quint64 cost) { // resulting format: 1.234E56 diff --git a/src/util.h b/src/util.h index aac76741d..4113c646d 100644 --- a/src/util.h +++ b/src/util.h @@ -53,6 +53,7 @@ struct HashCombine QString formatString(const QString& input, bool replaceEmptyString = true); QString formatSymbol(const Data::Symbol& symbol, bool replaceEmptyString = true); +QString formatSymbolExtended(const Data::Symbol& symbol); QString formatCost(quint64 cost); QString formatCostRelative(quint64 selfCost, quint64 totalCost, bool addPercentSign = false); QString formatTimeString(quint64 nanoseconds, bool shortForm = false); From 4e51442004877d5f37f59bb96ea9df5e9d42bf51 Mon Sep 17 00:00:00 2001 From: Lieven Hey Date: Mon, 8 Jan 2024 13:42:39 +0100 Subject: [PATCH 4/4] add test for Symbol::canDisassemble --- tests/modeltests/tst_disassemblyoutput.cpp | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/modeltests/tst_disassemblyoutput.cpp b/tests/modeltests/tst_disassemblyoutput.cpp index b67e9ff84..3f90dde05 100644 --- a/tests/modeltests/tst_disassemblyoutput.cpp +++ b/tests/modeltests/tst_disassemblyoutput.cpp @@ -357,6 +357,32 @@ private slots: } } + void testCanDisassemble_data() + { + QTest::addColumn("symbol"); + QTest::addColumn("canDisassemble"); + + QTest::newRow("normal symbol") << Data::Symbol(QStringLiteral("main"), 0x1159, 0x32805, {}, + QStringLiteral("/some/path"), {}, false, false) + << true; + QTest::newRow("relocated symbol") + << Data::Symbol(QStringLiteral("printf"), 0, 0, {}, QStringLiteral("/some/path"), {}, false, false) + << false; + QTest::newRow("inlined symbol") << Data::Symbol(QStringLiteral("main::memcpy"), 0x1159, 0x32805, {}, + QStringLiteral("/some/path"), {}, false, true) + << false; + QTest::newRow("unkown binary") << Data::Symbol(QStringLiteral("main"), 0x1159, 0x32805, {}, {}, {}, false, + false) + << false; + } + + void testCanDisassemble() + { + QFETCH(Data::Symbol, symbol); + QFETCH(bool, canDisassemble); + QCOMPARE(symbol.canDisassemble(), canDisassemble); + } + private: struct FunctionData {