This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[patch] bfd/dwarf2.c gives wrong line number for inlined code
- From: Cary Coutant <ccoutant at google dot com>
- To: Binutils <binutils at sourceware dot org>
- Date: Thu, 17 Sep 2009 17:00:05 -0700
- Subject: [patch] bfd/dwarf2.c gives wrong line number for inlined code
The following simple test case shows a problem with inlined code in
addr2line (running on x86_64/Linux):
$ cat foo.cc
#include <stdio.h>
void __attribute__((always_inline)) bar() {
printf ("Hello World\n"); // line 4
}
void __attribute__((always_inline)) foo() {
bar();
bar();
}
int main() {
foo(); // line 13
return 0; // line 14
}
$ g++ -g -o foo foo.cc
$ objdump -d foo
...
00000000004005b2 <main>:
4005b2: 55 push %rbp
4005b3: 48 89 e5 mov %rsp,%rbp
4005b6: bf c8 06 40 00 mov $0x4006c8,%edi
4005bb: e8 d8 fe ff ff callq 400498 <puts@plt>
4005c0: bf c8 06 40 00 mov $0x4006c8,%edi
4005c5: e8 ce fe ff ff callq 400498 <puts@plt>
4005ca: b8 00 00 00 00 mov $0x0,%eax
4005cf: c9 leaveq
4005d0: c3 retq
...
$ readelf -wL foo
...
CU: foo.cc:
File name Line number Starting address
foo.cc 3 0x400588
foo.cc 4 0x40058c
foo.cc 5 0x400596
foo.cc 7 0x400598
foo.cc 4 0x40059c
foo.cc 10 0x4005b0
foo.cc 12 0x4005b2
foo.cc 4 0x4005b6
foo.cc 14 0x4005ca
foo.cc 15 0x4005cf
...
$ addr2line -e foo 0x4005c5
.../foo.cc:14
The call at 0x4005c5 is inlined from bar (via foo), and should be
shown at line 4, but a test for line table rows that span functions in
bfd/dwarf2.c is getting in the way and forcing
lookup_address_in_line_info_table to return the line number from the
next row (line 14 starting at pc 0x4005ca).
As far as I can tell, this test for spanning functions should only be
checking when the function is not inlined. The following patch turns
this check off when inlined functions are involved, so addr2line
reports line 4 as it should.
Does this look OK? (No regressions on x86_64, but that doesn't mean
much since there are any addr2line tests to run.)
-cary
bfd/ChangeLog:
* dwarf2.c (lookup_address_in_line_info_table): Test for
inlined subroutine.
Index: dwarf2.c
===================================================================
RCS file: /cvs/src/src/bfd/dwarf2.c,v
retrieving revision 1.123
diff -u -p -r1.123 dwarf2.c
--- dwarf2.c 9 Sep 2009 21:38:57 -0000 1.123
+++ dwarf2.c 17 Sep 2009 23:20:25 -0000
@@ -1529,7 +1529,7 @@ lookup_address_in_line_info_table (struc
of the last line of the earlier one. This check is for GCC
2.95, which emits the first line number for a function late. */
- if (function != NULL)
+ if (function != NULL && function->tag != DW_TAG_inlined_subroutine)
{
bfd_vma lowest_pc;
struct arange *arange;