33

I'm running "perf" in the following way:

perf record -a --call-graph -p some_pid

perf report --call-graph --stdio

Then, I see this:

 1.60%     my_binary  my_binary                [.] my_func
           |
           --- my_func
              |          
              |--71.10%-- (nil)
              |          (nil)
              |          
               --28.90%-- 0x17f310000000a

I can't see which functions call my_func(). I see "nil" and "0x17f310000000a" instead. Am I doing something wrong? It is probably not a debug info problem because some symbols are shown while others are not shown.

More info:

  • I'm runnning CentOS 6.2 (kernel 2.6.32-220.4.1).
  • perf rpm - perf-2.6.32-279.5.2.el6.x86_64.
ant
  • 22,634
  • 36
  • 132
  • 182
erezz
  • 331
  • 1
  • 3
  • 3
  • Related: [Weird Backtrace in Perf](https://stackoverflow.com/q/60491534) - libraries often usually compiled normally, without `-fno-omit-frame-pointer`, so the `fp` method of backtracing won't work into / through their functions. For libc6 specifically, [perf record with --call-stack fp fails to unwind main function](https://stackoverflow.com/q/68081147) mentions some distros having a libc6-prof package with a version of it compiled with frame pointers, intended for use with profilers. – Peter Cordes Dec 07 '22 at 19:13

2 Answers2

35

Make sure you compiled the code with -fno-omit-frame-pointer gcc option.

udalmik
  • 7,838
  • 26
  • 40
Andriy
  • 351
  • 3
  • 3
  • 34
    or try `perf record --call-graph dwarf` (which works without frame-pointer) – maxy Jan 26 '15 at 15:50
  • install debuginfo packages for the code you profile, most of the time you'll need glibc, ie debuginfo-install glibc – Alec Istomin Dec 22 '16 at 21:41
  • So, `perf record --call-graph dwarf` does NOT work (for me), and actively PREVENTS a callgraph from being recorded, even if one compiled with `-fno-omit-frame-pointer` ... it took me many hours & hair-pulling before I realized that I MUST do `perf record --call-graph fp` to get a callgraph! – Linas Aug 18 '20 at 04:43
  • ```sudo perf record --call-graph lbr ``` works for intel processors, no need to do a specific compilation of the program – Osman Aug 29 '23 at 20:12
19

You're almost there, you're missing the -G option (you might need a more recent perf than the one installed on your system):

$ perf report --call-graph --stdio -G

From perf help report:

   -G, --inverted
       alias for inverted caller based call graph.
holygeek
  • 15,653
  • 1
  • 40
  • 50
  • 2
    -G just changes order of call stack printing in `perf report`; if there is no full call stack recorded to `perf.data` at time of `perf record`, `-G` option will not help. Just need to enable frame pointers or dwarf (may be not ported to rh's 2.6.32) to decode frames at time of `record`: http://www.brendangregg.com/perf.html#StackTraces "Omitting frame pointers is an evil compiler optimization that breaks debugger" – osgx Jul 09 '16 at 08:44
  • 4
    Note that `-G` on `perf record` (rather than `report`) selects by cgroup, in case anyone gets confusing errors about cgroups. – Craig Ringer Dec 04 '17 at 05:24