From 7cd91875557ee6c6f75c9ee37aab81b3ad839106 Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Tue, 23 Jan 2018 16:55:36 +0100 Subject: Forward the path to binary for a given symbol The path is useful for filtering. It enables us to exclude frames that point to system libraries for example. Change-Id: Ic181e8498ffb237727d6176094bd3724a5d6ed0d Reviewed-by: Milian Wolff --- app/perfsymboltable.cpp | 25 ++++++++++++++----------- app/perfsymboltable.h | 9 +++++---- app/perfunwind.cpp | 2 +- app/perfunwind.h | 5 +++-- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/app/perfsymboltable.cpp b/app/perfsymboltable.cpp index 0bd45b7..a71cc8c 100644 --- a/app/perfsymboltable.cpp +++ b/app/perfsymboltable.cpp @@ -362,7 +362,7 @@ static QByteArray demangle(const QByteArray &mangledName) return mangledName; } -int PerfSymbolTable::insertSubprogram(Dwarf_Die *top, Dwarf_Addr entry, qint32 binaryId, +int PerfSymbolTable::insertSubprogram(Dwarf_Die *top, Dwarf_Addr entry, qint32 binaryId, qint32 binaryPathId, qint32 inlineCallLocationId, bool isKernel) { int line = 0; @@ -375,13 +375,13 @@ int PerfSymbolTable::insertSubprogram(Dwarf_Die *top, Dwarf_Addr entry, qint32 b int locationId = m_unwind->resolveLocation(PerfUnwind::Location(entry, fileId, m_pid, line, column, inlineCallLocationId)); qint32 symId = m_unwind->resolveString(demangle(dieName(top))); - m_unwind->resolveSymbol(locationId, PerfUnwind::Symbol(symId, binaryId, isKernel)); + m_unwind->resolveSymbol(locationId, PerfUnwind::Symbol(symId, binaryId, binaryPathId, isKernel)); return locationId; } -int PerfSymbolTable::parseDie(Dwarf_Die *top, qint32 binaryId, Dwarf_Files *files, - Dwarf_Addr entry, bool isKernel, const QStack &stack) +int PerfSymbolTable::parseDie(Dwarf_Die *top, qint32 binaryId, qint32 binaryPathId, bool isKernel, + Dwarf_Files *files, Dwarf_Addr entry, const QStack &stack) { int tag = dwarf_tag(top); switch (tag) { @@ -409,16 +409,16 @@ int PerfSymbolTable::parseDie(Dwarf_Die *top, qint32 binaryId, Dwarf_Files *file } int callLocationId = m_unwind->resolveLocation(location); - return insertSubprogram(top, entry, binaryId, callLocationId, isKernel); + return insertSubprogram(top, entry, binaryId, binaryPathId, callLocationId, isKernel); } case DW_TAG_subprogram: - return insertSubprogram(top, entry, binaryId, -1, isKernel); + return insertSubprogram(top, entry, binaryId, binaryPathId, -1, isKernel); default: return -1; } } -void PerfSymbolTable::parseDwarf(Dwarf_Die *cudie, Dwarf_Addr bias, qint32 binaryId, +void PerfSymbolTable::parseDwarf(Dwarf_Die *cudie, Dwarf_Addr bias, qint32 binaryId, qint32 binaryPathId, bool isKernel) { // Iterate through all dwarf sections and establish parent/child relations for inline @@ -435,7 +435,8 @@ void PerfSymbolTable::parseDwarf(Dwarf_Die *cudie, Dwarf_Addr bias, qint32 binar Dwarf_Die *top = &(stack.last().die); Dwarf_Addr entry = 0; if (dwarf_entrypc(top, &entry) == 0 && entry != 0) - stack.last().locationId = parseDie(top, binaryId, files, entry + bias, isKernel, stack); + stack.last().locationId = parseDie(top, binaryId, binaryPathId, isKernel, + files, entry + bias, stack); Dwarf_Die child; if (dwarf_child(top, &child) == 0) { @@ -759,9 +760,11 @@ int PerfSymbolTable::lookupFrame(Dwarf_Addr ip, bool isKernel, } qint32 binaryId = -1; + qint32 binaryPathId = -1; quint64 elfStart = 0; if (elf.isValid()) { binaryId = m_unwind->resolveString(elf.originalFileName); + binaryPathId = m_unwind->resolveString(elf.originalPath); elfStart = elf.addr; } @@ -841,7 +844,7 @@ int PerfSymbolTable::lookupFrame(Dwarf_Addr ip, bool isKernel, addressLocation.parentLocationId = m_unwind->lookupLocation(functionLocation); if (die && !m_unwind->hasSymbol(addressLocation.parentLocationId)) - parseDwarf(die, bias, binaryId, isKernel); + parseDwarf(die, bias, binaryId, binaryPathId, isKernel); if (addressLocation.parentLocationId == -1) addressLocation.parentLocationId = m_unwind->resolveLocation(functionLocation); } @@ -849,7 +852,7 @@ int PerfSymbolTable::lookupFrame(Dwarf_Addr ip, bool isKernel, // no sufficient debug information. Use what we already know qint32 symId = m_unwind->resolveString(demangle(symname)); m_unwind->resolveSymbol(addressLocation.parentLocationId, - PerfUnwind::Symbol(symId, binaryId, isKernel)); + PerfUnwind::Symbol(symId, binaryId, binaryPathId, isKernel)); } } else { if (isKernel) { @@ -870,7 +873,7 @@ int PerfSymbolTable::lookupFrame(Dwarf_Addr ip, bool isKernel, if (!m_unwind->hasSymbol(addressLocation.parentLocationId)) { qint32 symId = m_unwind->resolveString(symname); m_unwind->resolveSymbol(addressLocation.parentLocationId, - PerfUnwind::Symbol(symId, binaryId, isKernel)); + PerfUnwind::Symbol(symId, binaryId, binaryPathId, isKernel)); } } diff --git a/app/perfsymboltable.h b/app/perfsymboltable.h index 7aba694..0070a16 100644 --- a/app/perfsymboltable.h +++ b/app/perfsymboltable.h @@ -118,11 +118,12 @@ private: qint32 m_pid; QByteArray symbolFromPerfMap(quint64 ip, GElf_Off *offset) const; - int parseDie(Dwarf_Die *top, qint32 binaryId, Dwarf_Files *files, Dwarf_Addr entry, - bool isKernel, const QStack &stack); - int insertSubprogram(Dwarf_Die *top, Dwarf_Addr entry, qint32 binaryId, + int parseDie(Dwarf_Die *top, qint32 binaryId, qint32 binaryPathId, bool isKernel, + Dwarf_Files *files, Dwarf_Addr entry, const QStack &stack); + int insertSubprogram(Dwarf_Die *top, Dwarf_Addr entry, qint32 binaryId, qint32 binaryPathId, qint32 inlineParent, bool isKernel); - void parseDwarf(Dwarf_Die *cudie, Dwarf_Addr bias, qint32 binaryId, bool isKernel); + void parseDwarf(Dwarf_Die *cudie, Dwarf_Addr bias, qint32 binaryId, qint32 binaryPathId, + bool isKernel); }; QT_BEGIN_NAMESPACE diff --git a/app/perfunwind.cpp b/app/perfunwind.cpp index c04c6e0..09aed4f 100644 --- a/app/perfunwind.cpp +++ b/app/perfunwind.cpp @@ -372,7 +372,7 @@ QDataStream &operator<<(QDataStream &stream, const PerfUnwind::Location &locatio QDataStream &operator<<(QDataStream &stream, const PerfUnwind::Symbol &symbol) { - return stream << symbol.name << symbol.binary << symbol.isKernel; + return stream << symbol.name << symbol.binary << symbol.path << symbol.isKernel; } static int frameCallback(Dwfl_Frame *state, void *arg) diff --git a/app/perfunwind.h b/app/perfunwind.h index 00571f6..3f46250 100644 --- a/app/perfunwind.h +++ b/app/perfunwind.h @@ -82,13 +82,14 @@ public: }; struct Symbol { - explicit Symbol(qint32 name = -1, qint32 binary = -1, + explicit Symbol(qint32 name = -1, qint32 binary = -1, qint32 path = -1, bool isKernel = false) : - name(name), binary(binary), isKernel(isKernel) + name(name), binary(binary), path(path), isKernel(isKernel) {} qint32 name; qint32 binary; + qint32 path; bool isKernel; }; -- cgit v1.2.3