Hey all, I stumbled upon a strange behavior while symbolizing a perf.data file with hotspot/perfparser/elfutils that I have trouble understanding. I hope it's ok to send this call for help here.
I'm running with elfutils 0.181, g++ 10.2, glibc 2.32 on archlinux with kernel 5.9.14. Code for the executable: https://github.com/KDAB/hotspot/blob/master/tests/test-clients/cpp-inlining/ main.cpp Then compile it and run with perf: ``` $ g++ -O2 -g main.cpp $ perf record ./a.out $ perf script --show-mmap-events | grep -E 'main|MMAP' | head a.out 108684 15892.199058: PERF_RECORD_MMAP2 108684/108684: [0x561875084000(0x1000) @ 0 fe:00 7997193 372428903]: r-xp /home/milian/ projects/kdab/rnd/hotspot/build/a.out ... a.out 108684 15892.200561: 391517 cycles:u: 561875084c1e main+0x1de (/home/milian/projects/kdab/rnd/hotspot/build/a.out) ``` The first MMAP event show us that there's a mapping starting at 0x561875084000 with a size of 0x1000 that belongs to the main executable, pgoff is 0. Later on, we see e.g. the instruction pointer address 0x561875084c1e being somehow mapped to main+0x1de by perf using the binutils libraries. What's odd is that this should give us the offset of main: ``` 0x561875084c1e - 0x561875084000 = 0xc1e 0xc1e - 0x1de = 0xa40 ``` But look at what we get from nm: ``` $ eu-nm ./a.out | grep main main | 0000000000001a40|GLOBAL|FUNC |00000000000002e5|main.cpp:33|.text ``` Note that the address in the symbol table is actually 0x1000 offset from the 0xa40 value we computed above... Can anyone explain that? GDB shows a similar behavior: ``` $ gdb a.out (gdb) b main Breakpoint 1 at 0x1a40: file ../tests/test-clients/cpp-inlining/main.cpp, line 34. (gdb) r Starting program: /home/milian/projects/kdab/rnd/hotspot/build/a.out Breakpoint 1, main () at ../tests/test-clients/cpp-inlining/main.cpp:34 34 { (gdb) p/x $rip $1 = 0x555555555a40 (gdb) p/x &main $2 = 0x555555555a40 (gdb) info proc mappings process 109516 Mapped address spaces: Start Addr End Addr Size Offset objfile 0x555555554000 0x555555555000 0x1000 0x0 /home/milian/ projects/kdab/rnd/hotspot/build/a.out 0x555555555000 0x555555556000 0x1000 0x0 /home/milian/ projects/kdab/rnd/hotspot/build/a.out 0x555555556000 0x555555558000 0x2000 0x0 /home/milian/ projects/kdab/rnd/hotspot/build/a.out 0x555555558000 0x555555559000 0x1000 0x1000 /home/milian/ projects/kdab/rnd/hotspot/build/a.out ... (gdb) ``` So here, the address `0x555555555a40` should come from the second mapping, which has an offset 0x0 and starts at `0x555555555000` and has a size of `0x1000`. How can that possibly map to the `main` symbol which has an offset of `0x1a40`? Does anyone know what's going on here? Thanks -- Milian Wolff m...@milianw.de http://milianw.de
signature.asc
Description: This is a digitally signed message part.