This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]