On Wed, 2016-10-05 at 17:45 +0200, Milian Wolff wrote:
I'm trying to improve Linux perf report by adding inliner
information to the
callstacks it reports, to make the output more easily interpretable when
looking at complicated C++ applications.
You might want to take a look at eu-stack (src/stack.c) in elfutils
which does this too. If you are using the elfutils libraries (libdw.so).
I have a proof of concept locally using bfd_find_inliner_info
I don't know what bfd_find_inliner_info is.
It sound like something from binutils?
, but have
noticed the following seemingly broken behavior:
int main(int argc, char** argv)
double a = 0;
double b = 0;
if (argc > 1)
a = atof(argv);
if (argc > 2)
b = atof(argv);
auto c = std::complex<double>(a, b);
std::cout << std::abs(c) << std::endl;
I build it with:
$ g++ -g -O2 -o test test.cpp
Then I get a "good" backtrace using GDB:
$ gdb ./test
(gdb) break hypot
Function "hypot" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (hypot) pending.
Starting program: /tmp/test
Breakpoint 1, 0x00007ffff776e910 in hypot () from /usr/lib/libm.so.6
#0 0x00007ffff776e910 in hypot () from /usr/lib/libm.so.6
#1 0x00000000004007f4 in std::__complex_abs (__z=<optimized out>) at /usr/
#2 std::abs<double> (__z=<synthetic pointer>) at /usr/include/c++/6.2.1/
#3 main (argc=<optimized out>, argv=<optimized out>) at test.cpp:14
Note what inliners it reports for the address 0x00000000004007f4. Let's try
bfd_find_inliner_info via eu-addr2line -i:
eu-addr2line -i -a 0x00000000004007f4 -e ./test
This is wrong and seems to be off-by-one:
eu-addr2line -i -a 0x00000000004007f3 -e ./test
Can someone with more knowledge in this area sched some light on what is going
on here please? Is it a bug, or is this fuzzy behavior and GDB happens to be
better at guessing the "right" thing?
I don't know what gdb exactly displays as address in that backtrace.
It might display the return address, in which case subtracting 1 is the
right thing to do on x86_64 (that would be an approximation of the call
address, which is what you want).
And in fact that is what eu-stack does:
(gdb) gcore test.core
Saved corefile test.core
$ eu-stack -v --core test.core --exec test
PID 32623 - core
#0 0x00007ffff77f8cf0 __hypot - libm.so.6
#1 0x0000000000400824 - 1 __complex_abs - test
#2 0x0000000000400824 - 1 abs<double> - test
#3 0x0000000000400824 - 1 main - test
#4 0x00007ffff721db35 - 1 __libc_start_main - libc.so.6
#5 0x000000000040088f - 1 _start - test