summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilian Wolff <milian.wolff@kdab.com>2018-01-23 16:55:36 +0100
committerUlf Hermann <ulf.hermann@qt.io>2019-05-03 12:38:15 +0000
commit7cd91875557ee6c6f75c9ee37aab81b3ad839106 (patch)
treeb057f43a960b66a62442c885e1bbe98574856c81
parentbaa5047dac301d56464720a9054c7e48095870c2 (diff)
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 <milian.wolff@kdab.com>
-rw-r--r--app/perfsymboltable.cpp25
-rw-r--r--app/perfsymboltable.h9
-rw-r--r--app/perfunwind.cpp2
-rw-r--r--app/perfunwind.h5
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<DieAndLocation> &stack)
+int PerfSymbolTable::parseDie(Dwarf_Die *top, qint32 binaryId, qint32 binaryPathId, bool isKernel,
+ Dwarf_Files *files, Dwarf_Addr entry, const QStack<DieAndLocation> &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<DieAndLocation> &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<DieAndLocation> &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;
};