[llvm] [llvm-profgen] Parse hex address suffixes in perf scripts (PR #219268)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 27 12:01:27 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-pgo
Author: Rahman Lavaee (rlavaee)
<details>
<summary>Changes</summary>
DSO/library names (e.g. ` [unknown]`, ` [libc.so.6]`) are appended to call stack addresses in perf scripts with perf5 . This causes `parseAddress` to fail because `getAsInteger` expects the entire input string to be the integer representation.
Fix this by using `take_while` to strip trailing whitespace/non-hex suffixes from the address token inside `parseAddress`. To prevent LBR lines from being mistakenly consumed as call stack entries in `checkPerfScriptType`'s detection loop, we add an explicit check to stop when an LBR line is encountered.
Added a new test case `callstack-dso-suffix.test` verifying correct parsing with different types of suffixes.
---
Full diff: https://github.com/llvm/llvm-project/pull/219268.diff
3 Files Affected:
- (added) llvm/test/tools/llvm-profgen/X86/Inputs/callstack-dso-suffix.perfscript (+23)
- (added) llvm/test/tools/llvm-profgen/X86/callstack-dso-suffix.test (+36)
- (modified) llvm/tools/llvm-profgen/PerfReader.cpp (+3)
``````````diff
diff --git a/llvm/test/tools/llvm-profgen/X86/Inputs/callstack-dso-suffix.perfscript b/llvm/test/tools/llvm-profgen/X86/Inputs/callstack-dso-suffix.perfscript
new file mode 100644
index 0000000000000..f101edf6282bf
--- /dev/null
+++ b/llvm/test/tools/llvm-profgen/X86/Inputs/callstack-dso-suffix.perfscript
@@ -0,0 +1,23 @@
+PERF_RECORD_MMAP2 2854748/2854748: [0x400000(0x1000) @ 0 00:1d 123291722 526021]: r-xp /home/noinline-cs-noprobe.perfbin
+
+ 4005dc [unknown]
+ 400634 [libc.so.6]
+ 400684
+ 7f68c5788793 [unknown]
+ 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 0x400645/0x4005ff/P/-/-/0 0x400637/0x400645/P/-/-/0 0x4005e9/0x400634/P/-/-/0 0x4005c8/0x4005dc/P/-/-/0
+
+// Test for leaf frame ending up in prolog
+ 4005b0 [libc.so.6]
+ 400684
+ 7f68c5788793 [unknown]
+ 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
+
+// Call stack:
+// 4005b0 -> start addr of bar
+// 400684 -> address in main
+// LBR Entry: | Source | Target
+// 0x40062f/0x4005b0/P/-/-/0 | callq -132 <bar> | start addr of bar
+// 0x400645/0x4005ff/P/-/-/0 | jmp -75 <foo+0xf> | movl -8(%rbp), %eax
+// 0x400637/0x400645/P/-/-/0 | jmp 9 <foo+0x55> | jmp -75 <foo+0xf>
+// 0x4005e9/0x400634/P/-/-/0 | (bar)retq | next addr of [callq -132 <bar>]
+// 0x4005d7/0x4005e5/P/-/-/0 | jmp 9 <bar+0x35> | movl -4(%rbp), %eax
diff --git a/llvm/test/tools/llvm-profgen/X86/callstack-dso-suffix.test b/llvm/test/tools/llvm-profgen/X86/callstack-dso-suffix.test
new file mode 100644
index 0000000000000..1e073d1432d22
--- /dev/null
+++ b/llvm/test/tools/llvm-profgen/X86/callstack-dso-suffix.test
@@ -0,0 +1,36 @@
+;; The test fails on Windows. Fix it before removing the following requirement.
+; REQUIRES: x86_64-linux
+; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/callstack-dso-suffix.perfscript --binary=%S/Inputs/noinline-cs-noprobe.perfbin --output=%t --skip-symbolization --profile-summary-cold-count=0
+; RUN: FileCheck %s --input-file %t --check-prefix=CHECK-UNWINDER
+; RUN: llvm-profgen --format=text --unsymbolized-profile=%t --binary=%S/Inputs/noinline-cs-noprobe.perfbin --output=%t1 --profile-summary-cold-count=0 --csspgo-preinliner=0 --gen-cs-nested-profile=0
+; RUN: FileCheck %s --input-file %t1
+
+; CHECK-UNWINDER: [main:1 @ foo]
+; CHECK-UNWINDER-NEXT: 3
+; CHECK-UNWINDER-NEXT: 5ff-62f:3
+; CHECK-UNWINDER-NEXT: 634-637:3
+; CHECK-UNWINDER-NEXT: 645-645:3
+; CHECK-UNWINDER-NEXT: 3
+; CHECK-UNWINDER-NEXT: 62f->5b0:3
+; CHECK-UNWINDER-NEXT: 637->645:3
+; CHECK-UNWINDER-NEXT: 645->5ff:3
+; CHECK-UNWINDER-NEXT: [main:1 @ foo:3 @ bar]
+; CHECK-UNWINDER-NEXT: 4
+; CHECK-UNWINDER-NEXT: 5b0-5c8:1
+; CHECK-UNWINDER-NEXT: 5b0-5d7:2
+; CHECK-UNWINDER-NEXT: 5dc-5e9:1
+; CHECK-UNWINDER-NEXT: 5e5-5e9:2
+; CHECK-UNWINDER-NEXT: 3
+; CHECK-UNWINDER-NEXT: 5c8->5dc:2
+; CHECK-UNWINDER-NEXT: 5d7->5e5:2
+; CHECK-UNWINDER-NEXT: 5e9->634:3
+
+; CHECK:[main:1 @ foo]:54:0
+; CHECK: 2: 3
+; CHECK: 3: 3 bar:3
+; CHECK:[main:1 @ foo:3 @ bar]:50:3
+; CHECK: 0: 3
+; CHECK: 1: 3
+; CHECK: 2: 2
+; CHECK: 4: 1
+; CHECK: 5: 3
diff --git a/llvm/tools/llvm-profgen/PerfReader.cpp b/llvm/tools/llvm-profgen/PerfReader.cpp
index c4fc4fb25166f..daabb5183d440 100644
--- a/llvm/tools/llvm-profgen/PerfReader.cpp
+++ b/llvm/tools/llvm-profgen/PerfReader.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
#include "PerfReader.h"
+#include <cctype>
#include "ErrorHandling.h"
#include "Options.h"
#include "ProfileGenerator.h"
@@ -708,6 +709,7 @@ void HybridPerfReader::unwindSamples() {
/// Parse a hex address from \p Str.
static bool parseAddress(StringRef Str, uint64_t &Addr, bool HasPrefix) {
+ Str = Str.take_while([](char C) { return !isspace(C); });
if (Str.consume_front("0x") != HasPrefix)
return true;
return Str.getAsInteger(16, Addr);
@@ -1264,6 +1266,7 @@ PerfContent PerfScriptReader::checkPerfScriptType(StringRef FileName) {
// Detect sample with call stack
int32_t Count = 0;
while (!TraceIt.isAtEoF() &&
+ !isLBRSample(TraceIt.getCurrentLine(), false) &&
!parseAddress(TraceIt.getCurrentLine().ltrim(), FrameAddr, false)) {
Count++;
TraceIt.advance();
``````````
</details>
https://github.com/llvm/llvm-project/pull/219268
More information about the llvm-commits
mailing list