Skip to content

Commit db88d92

Browse files
wlei-llvmtstellar
authored andcommitted
[CSSPGO][llvm-profgen] Fix bug with parsing hybrid sample trace line
when we skip the call stack starting with an external address, we should also skip the bottom LBR entry, otherwise it will cause a truncated context issue. Reviewed By: hoy, wenlei Differential Revision: https://reviews.llvm.org/D95480
1 parent 87c2702 commit db88d92

File tree

2 files changed

+13
-5
lines changed

2 files changed

+13
-5
lines changed

llvm/test/tools/llvm-profgen/Inputs/inline-cs-noprobe.perfscript

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
PERF_RECORD_MMAP2 2854748/2854748: [0x400000(0x1000) @ 0 00:1d 123291722 526021]: r-xp /home/inline-cs-noprobe.perfbin
22

3+
; test for an external or invalid top address, should skip the whole sample
4+
5+
ffffffff
6+
40067e
7+
5541f689495641d7
8+
0x4006c8/0x40067e/P/-/-/0 0x4006c8/0x40067e/P/-/-/0 0x4006c8/0x40067e/P/-/-/0 0x4006c8/0x40067e/P/-/-/0 0x4006c8/0x40067e/P/-/-/0 0x4006c8/0x40067e/P/-/-/0 0x4006c8/0x40067e/P/-/-/0 0x4006c8/0x40067e/P/-/-/0 0x4006c8/0x40067e/P/-/-/0 0x4006c8/0x40067e/P/-/-/0 0x4006c8/0x40067e/P/-/-/0 0x4006c8/0x40067e/P/-/-/0 0x40069b/0x400670/M/-/-/0 0x4006c8/0x40067e/P/-/-/0 0x4006c8/0x40067e/P/-/-/0 0x4006c8/0x40067e/P/-/-/0
39

410
40067e
511
5541f689495641d7

llvm/tools/llvm-profgen/PerfReader.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -437,11 +437,12 @@ bool PerfReader::extractCallstack(TraceStream &TraceIt,
437437
ProfiledBinary *Binary = nullptr;
438438
while (!TraceIt.isAtEoF() && !TraceIt.getCurrentLine().startswith(" 0x")) {
439439
StringRef FrameStr = TraceIt.getCurrentLine().ltrim();
440-
// We might get an empty line at the beginning or comments, skip it
441440
uint64_t FrameAddr = 0;
442441
if (FrameStr.getAsInteger(16, FrameAddr)) {
442+
// We might parse a non-perf sample line like empty line and comments,
443+
// skip it
443444
TraceIt.advance();
444-
break;
445+
return false;
445446
}
446447
TraceIt.advance();
447448
if (!Binary) {
@@ -468,9 +469,9 @@ bool PerfReader::extractCallstack(TraceStream &TraceIt,
468469
CallStack.emplace_back(FrameAddr);
469470
}
470471

471-
if (CallStack.empty())
472-
return false;
473472
// Skip other unrelated line, find the next valid LBR line
473+
// Note that even for empty call stack, we should skip the address at the
474+
// bottom, otherwise the following pass may generate a truncated callstack
474475
while (!TraceIt.isAtEoF() && !TraceIt.getCurrentLine().startswith(" 0x")) {
475476
TraceIt.advance();
476477
}
@@ -482,7 +483,8 @@ bool PerfReader::extractCallstack(TraceStream &TraceIt,
482483
// of such case - when sample landed in prolog/epilog, somehow stack
483484
// walking will be broken in an unexpected way that higher frames will be
484485
// missing.
485-
return !Binary->addressInPrologEpilog(CallStack.front());
486+
return !CallStack.empty() &&
487+
!Binary->addressInPrologEpilog(CallStack.front());
486488
}
487489

488490
void PerfReader::parseHybridSample(TraceStream &TraceIt) {

0 commit comments

Comments
 (0)