[memprof] Add a test to verify callstack order.

We add to ensure that we are observing the correct callstack order in memprof
during symbolization. There was some confusion whether the order of
DIFrame objects were reversed but in reality the leaf function is at
index 0 so no code changes are required.

Differential Revision: https://reviews.llvm.org/D121759
This commit is contained in:
Snehasish Kumar 2022-03-15 16:50:19 -07:00
parent 67f53708b2
commit 49c048add4
4 changed files with 111 additions and 0 deletions

View File

@ -327,6 +327,11 @@ Error RawMemProfReader::symbolizeAndFilterStackFrames() {
for (size_t I = 0; I < DI.getNumberOfFrames(); I++) {
const auto &Frame = DI.getFrame(I);
LLVM_DEBUG(
// Print out the name to guid mapping for debugging.
llvm::dbgs() << "FunctionName: " << Frame.FunctionName << " GUID: "
<< Function::getGUID(trimSuffix(Frame.FunctionName))
<< "\n";);
SymbolizedFrame[VAddr].emplace_back(
// We use the function guid which we expect to be a uint64_t. At
// this time, it is the lower 64 bits of the md5 of the function

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,106 @@
REQUIRES: x86_64-linux
The input raw profile test has been generated from the following source code:
```
#include <stdlib.h>
#include <string.h>
__attribute__((always_inline))
void qux(int x) {
char *ptr = malloc(x);
memset(ptr, 0, x);
free(ptr);
}
__attribute__((noinline))
void foo(int x){ qux(x); }
__attribute__((noinline))
void bar(int x) { foo(x); }
int main(int argc, char **argv) {
bar(argc);
return 0;
}
```
Compile and run with the following commands:
```
bin/clang -fuse-ld=lld -Wl,--no-rosegment -gmlt -fdebug-info-for-profiling \
-fmemory-profile -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer \
-fno-optimize-sibling-calls -m64 -Wl,-build-id inline.c -o memprof-inline.exe
env MEMPROF_OPTIONS=log_path=stdout ./memprof-inline.exe > inline.memprofraw
```
From a debug run we collect the name to guid mappings to ensure that the
ordering we observe is as expected.
```
build-dbg/bin/llvm-profdata show --memory --debug-only=memprof \
inline.memprofraw --profiled-binary memprof-inline.exe
FunctionName: qux GUID: 15505678318020221912
FunctionName: foo GUID: 6699318081062747564
FunctionName: bar GUID: 16434608426314478903
FunctionName: main GUID: 15822663052811949562
[..omit output here which is checked below..]
```
RUN: llvm-profdata show --memory %p/Inputs/inline.memprofraw --profiled-binary %p/Inputs/memprof-inline.exe
CHECK: MemprofProfile:
CHECK-NEXT: -
CHECK-NEXT: Header:
CHECK-NEXT: Version: 1
CHECK-NEXT: TotalSizeBytes: 880
CHECK-NEXT: NumSegments: 9
CHECK-NEXT: NumMibInfo: 2
CHECK-NEXT: NumStackOffsets: 2
CHECK-NEXT: Records:
CHECK-NEXT: -
CHECK-NEXT: Callstack:
CHECK-NEXT: -
CHECK-NEXT: Function: 15505678318020221912
CHECK-NEXT: LineOffset: 1
CHECK-NEXT: Column: 15
CHECK-NEXT: Inline: 0
CHECK-NEXT: -
CHECK-NEXT: Function: 6699318081062747564
CHECK-NEXT: LineOffset: 0
CHECK-NEXT: Column: 18
CHECK-NEXT: Inline: 1
CHECK-NEXT: -
CHECK-NEXT: Function: 16434608426314478903
CHECK-NEXT: LineOffset: 0
CHECK-NEXT: Column: 19
CHECK-NEXT: Inline: 0
CHECK-NEXT: -
CHECK-NEXT: Function: 15822663052811949562
CHECK-NEXT: LineOffset: 1
CHECK-NEXT: Column: 3
CHECK-NEXT: Inline: 0
CHECK-NEXT: MemInfoBlock:
CHECK-NEXT: AllocCount: 1
CHECK-NEXT: TotalAccessCount: 1
CHECK-NEXT: MinAccessCount: 1
CHECK-NEXT: MaxAccessCount: 1
CHECK-NEXT: TotalSize: 1
CHECK-NEXT: MinSize: 1
CHECK-NEXT: MaxSize: 1
CHECK-NEXT: AllocTimestamp: 894
CHECK-NEXT: DeallocTimestamp: 894
CHECK-NEXT: TotalLifetime: 0
CHECK-NEXT: MinLifetime: 0
CHECK-NEXT: MaxLifetime: 0
CHECK-NEXT: AllocCpuId: 23
CHECK-NEXT: DeallocCpuId: 23
CHECK-NEXT: NumMigratedCpu: 0
CHECK-NEXT: NumLifetimeOverlaps: 0
CHECK-NEXT: NumSameAllocCpu: 0
CHECK-NEXT: NumSameDeallocCpu: 0
CHECK-NEXT: DataTypeId: {{[0-9]+}}