hoy updated this revision to Diff 372604.
hoy added a comment.
Addressing Wenlei's comment.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D109638/new/
https://reviews.llvm.org/D109638
Files:
llvm/test/tools/llvm-profgen/Inputs/cs-invalid-ret-addr.perfscript
llvm/test/tools/llvm-profgen/cs-invalid-ret-addr.test
llvm/tools/llvm-profgen/PerfReader.cpp
llvm/tools/llvm-profgen/PerfReader.h
llvm/tools/llvm-profgen/ProfiledBinary.h
Index: llvm/tools/llvm-profgen/ProfiledBinary.h
===================================================================
--- llvm/tools/llvm-profgen/ProfiledBinary.h
+++ llvm/tools/llvm-profgen/ProfiledBinary.h
@@ -299,7 +299,11 @@
}
uint64_t getCallAddrFromFrameAddr(uint64_t FrameAddr) const {
- return getAddressforIndex(getIndexForAddr(FrameAddr) - 1);
+ auto I = getIndexForAddr(FrameAddr);
+ FrameAddr = I ? getAddressforIndex(I - 1) : 0;
+ if (FrameAddr && addressIsCall(FrameAddr))
+ return FrameAddr;
+ return 0;
}
StringRef getFuncFromStartOffset(uint64_t Offset) {
Index: llvm/tools/llvm-profgen/PerfReader.h
===================================================================
--- llvm/tools/llvm-profgen/PerfReader.h
+++ llvm/tools/llvm-profgen/PerfReader.h
@@ -594,6 +594,8 @@
void parseEventOrSample(TraceStream &TraceIt);
// Warn if the relevant mmap event is missing.
void warnIfMissingMMap();
+ // Emit accumulate warnings.
+ void emitAccumulatedWarnings();
// Extract call stack from the perf trace lines
bool extractCallstack(TraceStream &TraceIt,
SmallVectorImpl<uint64_t> &CallStack);
@@ -619,6 +621,8 @@
// Samples with the repeating time generated by the perf reader
AggregatedCounter AggregatedSamples;
PerfScriptType PerfType = PERF_UNKNOWN;
+ // Keep track of all invalid return addresses
+ std::set<uint64_t> InvalidReturnAddresses;
};
/*
Index: llvm/tools/llvm-profgen/PerfReader.cpp
===================================================================
--- llvm/tools/llvm-profgen/PerfReader.cpp
+++ llvm/tools/llvm-profgen/PerfReader.cpp
@@ -9,13 +9,15 @@
#include "ProfileGenerator.h"
#include "llvm/Support/FileSystem.h"
+#define DEBUG_TYPE "perf-reader"
+
static cl::opt<bool> ShowMmapEvents("show-mmap-events", cl::ReallyHidden,
cl::init(false), cl::ZeroOrMore,
cl::desc("Print binary load events."));
cl::opt<bool> SkipSymbolization("skip-symbolization", cl::ReallyHidden,
cl::init(false), cl::ZeroOrMore,
- cl::desc("Dump the unsumbolized profile to the "
+ cl::desc("Dump the unsymbolized profile to the "
"output file. It will show unwinder "
"output for CS profile generation."));
@@ -517,10 +519,17 @@
if (!Binary->addressIsCode(FrameAddr))
break;
- // We need to translate return address to call address
- // for non-leaf frames
+ // We need to translate return address to call address for non-leaf frames.
if (!CallStack.empty()) {
- FrameAddr = Binary->getCallAddrFromFrameAddr(FrameAddr);
+ auto CallAddr = Binary->getCallAddrFromFrameAddr(FrameAddr);
+ if (!CallAddr) {
+ // Stop at an invalid return address caused by bad unwinding. This could
+ // happen to frame-pointer-based unwinding and the callee functions that
+ // do not have the frame pointer chain set up.
+ InvalidReturnAddresses.insert(FrameAddr);
+ break;
+ }
+ FrameAddr = CallAddr;
}
CallStack.emplace_back(FrameAddr);
@@ -760,12 +769,20 @@
void HybridPerfReader::generateRawProfile() { unwindSamples(); }
+void PerfReaderBase::emitAccumulatedWarnings() {
+ for (auto Address : InvalidReturnAddresses) {
+ WithColor::warning() << "Invalid return address "
+ << format("%" PRIx64, Address) << "\n";
+ }
+}
+
void PerfReaderBase::parsePerfTraces(
cl::list<std::string> &PerfTraceFilenames) {
// Parse perf traces and do aggregation.
for (auto Filename : PerfTraceFilenames)
parseAndAggregateTrace(Filename);
+ emitAccumulatedWarnings();
generateRawProfile();
}
Index: llvm/test/tools/llvm-profgen/cs-invalid-ret-addr.test
===================================================================
--- /dev/null
+++ llvm/test/tools/llvm-profgen/cs-invalid-ret-addr.test
@@ -0,0 +1,4 @@
+; REQUIRES: x86_64-linux
+; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/cs-invalid-ret-addr.perfscript --binary=%S/Inputs/noinline-cs-noprobe.perfbin --output=%t 2>&1 | FileCheck %s
+
+; CHECK: warning: Invalid return address 400686
Index: llvm/test/tools/llvm-profgen/Inputs/cs-invalid-ret-addr.perfscript
===================================================================
--- /dev/null
+++ llvm/test/tools/llvm-profgen/Inputs/cs-invalid-ret-addr.perfscript
@@ -0,0 +1,12 @@
+PERF_RECORD_MMAP2 2854748/2854748: [0x400000(0x1000) @ 0 00:1d 123291722 526021]: r-xp /home/noinline-cs-noprobe.perfbin
+// test for invalid return address
+
+ 4005b0
+ 400686
+ 7f68c5788793
+ 0x40062f/0x4005b0/P/-/-/0 0x400645/0x4005ff/P/-/-/0 0x400637/0x400645/P/-/-/0 0x4005e9/0x400634/P/-/-/0 0x4005c8/0x4005dc/P/-/-/0 0x40062f/0x4005b0/P/-/-/0 0x400645/0x4005ff/P/-/-/0 0x400637/0x400645/P/-/-/0 0x4005e9/0x400634/P/-/-/0 0x4005d7/0x4005e5/P/-/-/0 0x40062f/0x4005b0/P/-/-/0 0x400645/0x4005ff/P/-/-/0 0x400637/0x400645/P/-/-/0 0x4005e9/0x400634/P/-/-/0 0x4005d7/0x4005e5/P/-/-/0 0x40062f/0x4005b0/P/-/-/0
+
+ 4005b2
+ 400686
+ 7f68c5788793
+ 0x40062f/0x4005b0/P/-/-/0 0x400645/0x4005ff/P/-/-/0 0x400637/0x400645/P/-/-/0 0x4005e9/0x400634/P/-/-/0 0x4005c8/0x4005dc/P/-/-/0 0x40062f/0x4005b0/P/-/-/0 0x400645/0x4005ff/P/-/-/0 0x400637/0x400645/P/-/-/0 0x4005e9/0x400634/P/-/-/0 0x4005d7/0x4005e5/P/-/-/0 0x40062f/0x4005b0/P/-/-/0 0x400645/0x4005ff/P/-/-/0 0x400637/0x400645/P/-/-/0 0x4005e9/0x400634/P/-/-/0 0x4005d7/0x4005e5/P/-/-/0 0x40062f/0x4005b0/P/-/-/0
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits