Bug 23715

Summary: addr2line reports null symbol for inline frame
Product: binutils Reporter: Milian Wolff <mail>
Component: binutilsAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: mail, nickc
Priority: P2    
Version: 2.31   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:
Attachments: correctly pass through name from nested find_abstract_instance calls

Description Milian Wolff 2018-09-26 12:48:53 UTC
Since some time addr2line, and libbfd as used by perf, fail to associate the symbol name to inlined frames. Note the "??" in the output of addr2line in the reproducer below:

$ cat test.cpp 
#include <cmath>
#include <complex>
#include <iostream>
#include <random>

using namespace std;

int main()
{
    uniform_real_distribution<double> uniform(-1E5, 1E5);
    default_random_engine engine;
    double s = 0;
    for (int i = 0; i < 10000000; ++i) {
        s += norm(complex<double>(uniform(engine), uniform(engine)));
    }
    return static_cast<int>(s);
}
$ g++ -g -O2 test.cpp
$ addr2line -e a.out 766 -if
main
/usr/include/c++/8.2.1/bits/random.tcc:123
??
/usr/include/c++/8.2.1/bits/random.h:257
main
/tmp/test.cpp:11

I'm using libbfd 2.31.1 with gcc 8.2.1 or clang 6.0.1 currently. eu-addr2line seems to work correctly, which makes me believe it's an issue with libbfd / addr2line from binutils:

$ eu-addr2line -e a.out 766 -if
_ZNSt26linear_congruential_engineImLm16807ELm0ELm2147483647EE4seedEm inlined at /usr/include/c++/8.2.1/bits/random.h:257:9 in main
/usr/include/c++/8.2.1/bits/random.tcc:123:2
_ZNSt26linear_congruential_engineImLm16807ELm0ELm2147483647EEC4Em
/usr/include/c++/8.2.1/bits/random.h:257:9
main
/tmp/test.cpp:11:27
Comment 1 Milian Wolff 2018-09-26 13:42:54 UTC
Created attachment 11274 [details]
correctly pass through name from nested find_abstract_instance calls

The attached patch fixes the issue for me. Apparently the compilers generate debug information with nested instance, i.e. find_abstract_instance calls itself in dwarf2.c. In such a scenario, the inner call will correctly set its pname to the name it found. But the outer call will then override it with name = NULL at the end of find_abstract_instance.

Fix this by passing the pointer to the name when calling find_abstract_instance from itself. I've tested this patch with addr2line and perf on the example source code provided in the bug report. Both work again with this fix applied!
Comment 2 Milian Wolff 2018-09-26 13:46:55 UTC
are there really no unit tests for libbfd?
Comment 3 Sourceware Commits 2018-10-03 11:07:41 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=c8d3f93237d77f76d14e09e44bc770ce9428b0e4

commit c8d3f93237d77f76d14e09e44bc770ce9428b0e4
Author: Millan Wolff <mail@milianw.de>
Date:   Wed Oct 3 12:06:09 2018 +0100

    Fix the handling of inlined frames in DWARF debug info.
    
    	PR 23715
    	* dwarf2.c (find_abstract_instance): Allow recursive invocations
    	of find_abstract_instance to override the name variable.
Comment 4 Nick Clifton 2018-10-03 11:26:21 UTC
Hi Milian,

  Thanks for the bug report and patch.  I have now checked the patch
  in to the mainline sources.

  In answer to your question, "no - there are currently no unit tests
  for the binutils".  This is not because there is a policy against
  them, but rather because no-one has had the time and energy to add
  the necessary framework and then start writing the tests.  Of course
  volunteers are always welcome.

Cheers
  Nick
Comment 5 Milian Wolff 2018-10-08 10:56:08 UTC
Thanks a lot for merging the patch and providing the background information. I was asking mostly because I was wondering whether my patch was missing a unit test.

Cheers