https://sourceware.org/bugzilla/show_bug.cgi?id=19315
Bug ID: 19315 Summary: addr2line change for C++ symbols breaks behavior for inlined functions Product: binutils Version: 2.25 Status: NEW Severity: normal Priority: P2 Component: binutils Assignee: unassigned at sourceware dot org Reporter: pcarroll at codesourcery dot com Target Milestone: --- Created attachment 8818 --> https://sourceware.org/bugzilla/attachment.cgi?id=8818&action=edit C++ test case This issue is a side effect of the change for bug #17541 (https://sourceware.org/bugzilla/show_bug.cgi?id=17541). That change was to have addr2line (through the use of BFD dwarf2.c) identify C++ symbols in debug information that could be missing namespace, class, and other information but have no linkage name, and then find a matching symbol in the ELF symbol table. I compiled my enclosed test case with g++ 5.2.0, with the '-g -O2' options, for ARM Linux. I then inspected the DWARF2 information for my resulting executable and found the debug information for my 'main' subprogram. The DWARF2 information then showed 2 following inlined functions. The first inlined function mapped to the 'func1' class member, which had a linkage name of '_Z5func1i'. The second inlined function mapped to the 'myfunc' C function, which has no linkage name. In my example, the low_pc address for 'myfunc' is 0x103cc. (I'm not sure there is a way to figure out the appropriate address without just inspecting an executable. So, of course, I would expect a different address for a test case compiled with a different toolchain.) With that in mind, I run addr2line 2.25.51 on the resulting executable, with the arguments '-f -i -e addr2test2 103ce', so it maps into the innermost function. This produces the following output: main /bug/addr2test2.h:4 _Z5func1i /bug/addr2test2.cpp:23 main /bug/addr2test2.cpp:32 As we can see, this returns the name of the outermost function 'main' rather than the innermost function 'myfunc' for the first function name. When I investigated this issue, I believe it ties into the code at the end of '_bfd_dwarf2_find_nearest_line'. There, the code checks if is_linkage is set for a function. If not (i.e., it is C++ or similar), then a call to '_bfd_elf_find_function' is made. That will find a symbol in the ELF symbol table, which is, of course, the outermost function name. The inlined function names are not found by this means. That is not a problem if the linkage name is present. But that is not always the case, such as for an inlined C function, as occurred here. I believe this can be avoided by modifying '_bfd_elf_find_function' in dwarf2.c, to have it return a pointer to the symbol that is found. Then, after '_bfd_elf_find_function' is called for symbols without a linkage symbol, the value of the ELF symbol is compared against the DWARF's low_pc value. The test I used was: if ((matching_sym->value+section->vma) == function->arange.low) I'm not sure if that is the best way to see if these addresses are the same, but that worked for me. If the addresses are the same, then using the ELF symbol is appropriate. If the addresses are different, though, then the DWARF2 symbol is appropriate. That is true whether the symbol is an embedded C function, such as is my example, or it is a C++ symbol that has no linkage name and is somehow missing namespace, class, or other information. Some information seems better than wrong information. When I ran my modified addr2line function, I got the following output: myfunc /bug/addr2test2.h:4 _Z5func1i /bug/addr2test2.cpp:23 main /bug/addr2test2.cpp:32 That, I think, is the best we can hope for. And that also matches what is seen with addr2line 2.24.51. -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils