summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarya Knysh <d.knysh@nips.ru>2020-12-14 13:26:36 +0700
committerDarya Knysh <d.knysh@nips.ru>2020-12-15 08:40:51 +0000
commitdb1a1848f961b14e0187f3121e62dbca31da2e00 (patch)
tree04e2c3ef6accdf4fa3999fe58b6cb5d8dc9b83a4
parent908bb5c48ecbf90e0663dbff0045d40b19481021 (diff)
Add actual file path computation for symbols
Actual file path can differ from perf recorded. Compute and pass it to hotspot through Symbol struct field actualPath. Change-Id: I556035234cbcffa42497bf02e225d63565e4a0bf Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r--app/perfsymboltable.cpp22
-rw-r--r--app/perfsymboltable.h6
-rw-r--r--app/perfunwind.cpp2
-rw-r--r--app/perfunwind.h5
-rw-r--r--tests/auto/shared/perfparsertestclient.cpp2
-rw-r--r--tests/auto/shared/perfparsertestclient.h1
6 files changed, 21 insertions, 17 deletions
diff --git a/app/perfsymboltable.cpp b/app/perfsymboltable.cpp
index 795cffd..d5320e3 100644
--- a/app/perfsymboltable.cpp
+++ b/app/perfsymboltable.cpp
@@ -318,7 +318,7 @@ void PerfSymbolTable::registerElf(const PerfRecordMmap &mmap, const QByteArray &
int PerfSymbolTable::insertSubprogram(CuDieRangeMapping *cudie, Dwarf_Die *top, Dwarf_Addr entry,
quint64 offset, quint64 size, quint64 relAddr,
- qint32 binaryId, qint32 binaryPathId,
+ qint32 binaryId, qint32 binaryPathId, qint32 actualPathId,
qint32 inlineCallLocationId, bool isKernel)
{
int line = 0;
@@ -331,12 +331,12 @@ int PerfSymbolTable::insertSubprogram(CuDieRangeMapping *cudie, Dwarf_Die *top,
int locationId = m_unwind->resolveLocation(PerfUnwind::Location(entry, relAddr, fileId, m_pid, line,
column, inlineCallLocationId));
qint32 symId = m_unwind->resolveString(cudie->dieName(top));
- m_unwind->resolveSymbol(locationId, PerfUnwind::Symbol(symId, offset, size, binaryId, binaryPathId, isKernel));
+ m_unwind->resolveSymbol(locationId, PerfUnwind::Symbol{symId, offset, size, binaryId, binaryPathId, actualPathId, isKernel});
return locationId;
}
-int PerfSymbolTable::parseDie(CuDieRangeMapping *cudie, Dwarf_Die *top, quint64 offset, quint64 size, quint64 relAddr, qint32 binaryId, qint32 binaryPathId,
+int PerfSymbolTable::parseDie(CuDieRangeMapping *cudie, Dwarf_Die *top, quint64 offset, quint64 size, quint64 relAddr, qint32 binaryId, qint32 binaryPathId, qint32 actualPathId,
bool isKernel, Dwarf_Files *files, Dwarf_Addr entry, qint32 parentLocationId)
{
int tag = dwarf_tag(top);
@@ -360,17 +360,17 @@ int PerfSymbolTable::parseDie(CuDieRangeMapping *cudie, Dwarf_Die *top, quint64
location.parentLocationId = parentLocationId;
int callLocationId = m_unwind->resolveLocation(location);
- return insertSubprogram(cudie, top, entry, offset, size, relAddr, binaryId, binaryPathId, callLocationId, isKernel);
+ return insertSubprogram(cudie, top, entry, offset, size, relAddr, binaryId, binaryPathId, actualPathId, callLocationId, isKernel);
}
case DW_TAG_subprogram:
- return insertSubprogram(cudie, top, entry, offset, size, relAddr, binaryId, binaryPathId, -1, isKernel);
+ return insertSubprogram(cudie, top, entry, offset, size, relAddr, binaryId, binaryPathId, actualPathId, -1, isKernel);
default:
return -1;
}
}
qint32 PerfSymbolTable::parseDwarf(CuDieRangeMapping *cudie, SubProgramDie *subprogram, const QVector<Dwarf_Die> &inlined,
- Dwarf_Addr bias, quint64 offset, quint64 size, quint64 relAddr, qint32 binaryId, qint32 binaryPathId, bool isKernel)
+ Dwarf_Addr bias, quint64 offset, quint64 size, quint64 relAddr, qint32 binaryId, qint32 binaryPathId, qint32 actualPathId, bool isKernel)
{
Dwarf_Files *files = nullptr;
dwarf_getsrcfiles(cudie->cudie(), &files, nullptr);
@@ -382,7 +382,7 @@ qint32 PerfSymbolTable::parseDwarf(CuDieRangeMapping *cudie, SubProgramDie *subp
if (dwarf_entrypc(&scope, &entry) == 0 && entry != 0)
scopeAddr += entry;
- auto locationId = parseDie(cudie, &scope, offset, size, relAddr, binaryId, binaryPathId, isKernel, files, scopeAddr, parentLocationId);
+ auto locationId = parseDie(cudie, &scope, offset, size, relAddr, binaryId, binaryPathId, actualPathId, isKernel, files, scopeAddr, parentLocationId);
if (locationId != -1)
parentLocationId = locationId;
};
@@ -766,10 +766,12 @@ int PerfSymbolTable::lookupFrame(Dwarf_Addr ip, bool isKernel,
qint32 binaryId = -1;
qint32 binaryPathId = -1;
+ qint32 actualPathId = -1;
quint64 elfStart = 0;
if (elf.isValid()) {
binaryId = m_unwind->resolveString(elf.originalFileName);
binaryPathId = m_unwind->resolveString(elf.originalPath);
+ actualPathId = m_unwind->resolveString(elf.localFile.absoluteFilePath().toUtf8());
elfStart = elf.hasBaseAddr() ? elf.baseAddr : elf.addr;
}
@@ -842,7 +844,7 @@ int PerfSymbolTable::lookupFrame(Dwarf_Addr ip, bool isKernel,
// otherwise resolve the inline chain if possible
if (!scopes.isEmpty() && !m_unwind->hasSymbol(addressLocation.parentLocationId)) {
functionLocation.parentLocationId = parseDwarf(cudie, subprogram, scopes, bias, start, size, relAddr,
- binaryId, binaryPathId, isKernel);
+ binaryId, binaryPathId, actualPathId, isKernel);
}
}
}
@@ -860,7 +862,7 @@ int PerfSymbolTable::lookupFrame(Dwarf_Addr ip, bool isKernel,
// no sufficient debug information. Use what we already know
qint32 symId = m_unwind->resolveString(symname);
m_unwind->resolveSymbol(addressLocation.parentLocationId,
- PerfUnwind::Symbol(symId, start, size, binaryId, binaryPathId, isKernel));
+ PerfUnwind::Symbol(symId, start, size, binaryId, binaryPathId, actualPathId, isKernel));
}
} else {
if (isKernel) {
@@ -881,7 +883,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, start, size, binaryId, binaryPathId, isKernel));
+ PerfUnwind::Symbol(symId, start, size, binaryId, binaryPathId, actualPathId, isKernel));
}
}
// relAddr - relative address of the function start added with offset from the function start
diff --git a/app/perfsymboltable.h b/app/perfsymboltable.h
index 23b8f65..49bf852 100644
--- a/app/perfsymboltable.h
+++ b/app/perfsymboltable.h
@@ -122,12 +122,12 @@ private:
qint32 m_pid;
QByteArray symbolFromPerfMap(quint64 ip, GElf_Off *offset) const;
- int parseDie(CuDieRangeMapping *cudie, Dwarf_Die *top, quint64 offset, quint64 size, quint64 relAddr, qint32 binaryId, qint32 binaryPathId, bool isKernel,
+ int parseDie(CuDieRangeMapping *cudie, Dwarf_Die *top, quint64 offset, quint64 size, quint64 relAddr, qint32 binaryId, qint32 binaryPathId, qint32 actualPathId, bool isKernel,
Dwarf_Files *files, Dwarf_Addr entry, qint32 parentLocationId);
- int insertSubprogram(CuDieRangeMapping *cudie, Dwarf_Die *top, Dwarf_Addr entry, quint64 offset, quint64 size, quint64 relAddr, qint32 binaryId, qint32 binaryPathId,
+ int insertSubprogram(CuDieRangeMapping *cudie, Dwarf_Die *top, Dwarf_Addr entry, quint64 offset, quint64 size, quint64 relAddr, qint32 binaryId, qint32 binaryPathId, qint32 actualPathId,
qint32 inlineParent, bool isKernel);
qint32 parseDwarf(CuDieRangeMapping *cudie, SubProgramDie *subprogram, const QVector<Dwarf_Die> &inlined,
- Dwarf_Addr bias, quint64 offset, quint64 size, quint64 relAddr, qint32 binaryId, qint32 binaryPathId, bool isKernel);
+ Dwarf_Addr bias, quint64 offset, quint64 size, quint64 relAddr, qint32 binaryId, qint32 binaryPathId, qint32 actualPathId, bool isKernel);
};
QT_BEGIN_NAMESPACE
diff --git a/app/perfunwind.cpp b/app/perfunwind.cpp
index 42af44b..0fdad1a 100644
--- a/app/perfunwind.cpp
+++ b/app/perfunwind.cpp
@@ -366,7 +366,7 @@ QDataStream &operator<<(QDataStream &stream, const PerfUnwind::Location &locatio
QDataStream &operator<<(QDataStream &stream, const PerfUnwind::Symbol &symbol)
{
- return stream << symbol.name << symbol.binary << symbol.path << symbol.isKernel << symbol.relAddr << symbol.size;
+ return stream << symbol.name << symbol.binary << symbol.path << symbol.isKernel << symbol.relAddr << symbol.size << symbol.actualPath;
}
static int frameCallback(Dwfl_Frame *state, void *arg)
diff --git a/app/perfunwind.h b/app/perfunwind.h
index 6e726b9..ff355b1 100644
--- a/app/perfunwind.h
+++ b/app/perfunwind.h
@@ -81,9 +81,9 @@ public:
};
struct Symbol {
- explicit Symbol(qint32 name = -1, quint64 relAddr = 0, quint64 size = 0, qint32 binary = -1, qint32 path = -1,
+ explicit Symbol(qint32 name = -1, quint64 relAddr = 0, quint64 size = 0, qint32 binary = -1, qint32 path = -1, qint32 actualPath = -1,
bool isKernel = false) :
- name(name), relAddr(relAddr), size(size), binary(binary), path(path), isKernel(isKernel)
+ name(name), relAddr(relAddr), size(size), binary(binary), path(path), actualPath(actualPath), isKernel(isKernel)
{}
qint32 name;
@@ -91,6 +91,7 @@ public:
quint64 size;
qint32 binary;
qint32 path;
+ qint32 actualPath;
bool isKernel;
};
diff --git a/tests/auto/shared/perfparsertestclient.cpp b/tests/auto/shared/perfparsertestclient.cpp
index 43702ce..ce7482c 100644
--- a/tests/auto/shared/perfparsertestclient.cpp
+++ b/tests/auto/shared/perfparsertestclient.cpp
@@ -117,7 +117,7 @@ void PerfParserTestClient::extractTrace(QIODevice *device)
case SymbolDefinition: {
qint32 id;
SymbolEvent symbol;
- stream >> id >> symbol.name >> symbol.binary >> symbol.path >> symbol.isKernel >> symbol.relAddr >> symbol.size;
+ stream >> id >> symbol.name >> symbol.binary >> symbol.path >> symbol.isKernel >> symbol.relAddr >> symbol.size >> symbol.actualPath;
if (symbol.name != -1)
checkString(symbol.name);
if (symbol.binary != -1)
diff --git a/tests/auto/shared/perfparsertestclient.h b/tests/auto/shared/perfparsertestclient.h
index 06c6c83..fbb56a3 100644
--- a/tests/auto/shared/perfparsertestclient.h
+++ b/tests/auto/shared/perfparsertestclient.h
@@ -77,6 +77,7 @@ public:
quint64 size = 0;
qint32 binary = -1;
qint32 path = -1;
+ qint32 actualPath = -1;
bool isKernel = false;
};