This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG0057c7185d1c: [CSSPGO][llvm-profgen] Truncate stack samples 
with invalid return address. (authored by hoy).

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 warnTruncatedStack();
   // 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,22 @@
 
 void HybridPerfReader::generateRawProfile() { unwindSamples(); }
 
+void PerfReaderBase::warnTruncatedStack() {
+  for (auto Address : InvalidReturnAddresses) {
+    WithColor::warning()
+        << "Truncated stack sample due to invalid return address at "
+        << format("0x%" PRIx64, Address)
+        << ", likely caused by frame pointer omission\n";
+  }
+}
+
 void PerfReaderBase::parsePerfTraces(
     cl::list<std::string> &PerfTraceFilenames) {
   // Parse perf traces and do aggregation.
   for (auto Filename : PerfTraceFilenames)
     parseAndAggregateTrace(Filename);
 
+  warnTruncatedStack();
   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: Truncated stack sample due to invalid return address at 0x400686, likely caused by frame pointer omission
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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to