bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug gold/10400] New: Gold produces incorrect debug and unwind info when


From: ppluzhnikov at google dot com
Subject: [Bug gold/10400] New: Gold produces incorrect debug and unwind info when incompatible COMDAT sections are present
Date: 15 Jul 2009 20:38:23 -0000

When multiple incompatible COMDAT sections are present, gold selects one,
but doesn't discard .debug_* and .eh_frame bits which refer to the other ones.

This then shows up as glitches in debugging the resulting executable under GDB.

Test:

--- cut --- test.h ---
#include <stdio.h>

inline int foo() {
  return 3;
}

extern char buf[4];
inline void HelloWorld() {
  // just some code to mess with stack layout
  printf("memcmp(): %d\n", __builtin_memcmp(buf, "abc", sizeof(buf)));
  printf("Hello %d\n", foo());
}
--- cut --- test.h ---

--- cut --- test1.cc ---
#include "test.h"

void Trampoline(void (*fn)() = HelloWorld);

char buf[4] = "abc";
int main() {
  HelloWorld();
  Trampoline();
  return 0;
}
--- cut --- test1.cc ---

--- cut --- test2.cc ---
#include "test.h"

void Trampoline(void (*fn)() = HelloWorld) {
  fn();
}

void NotCalled() {
  Trampoline();
}
--- cut --- test2.cc ---


./ld --version
GNU gold (GNU Binutils 2.19.51.20090714) 1.9
...

g++ -g -c test1.cc && g++ -g -c test2.cc -O2 && 
g++ -g test1.o test2.o -B. -o test-gold

First the unwind info:

nm test-gold | grep HelloWorld
00000000004002fe W _Z10HelloWorldv

readelf -wf test-gold    # contains inconsistent unwind descriptors:

# from test1.o, corresponds to code actually used
000000a8 00000024 0000004c FDE cie=00000060 pc=004002fe..0040033f
  DW_CFA_advance_loc4: 1 to 004002ff
  DW_CFA_def_cfa_offset: 16
  DW_CFA_offset: r6 at cfa-16
  DW_CFA_advance_loc4: 3 to 00400302
  DW_CFA_def_cfa_reg: r6
  DW_CFA_nop

# from test2.o, corresponds to discarded code
000000d8 0000001c 00000090 FDE cie=00000090 pc=004002fe..00400343
  DW_CFA_advance_loc4: 5 to 00400303
  DW_CFA_def_cfa_offset: 16
  DW_CFA_nop


This shows up as a glitch in GDB:

(gdb) b *&HelloWorld
Breakpoint 1 at 0x4002fe: file test.h, line 10.
(gdb) r

Breakpoint 1, HelloWorld () at test.h:10
10        printf("memcmp(): %d\n", __builtin_memcmp(buf, "abc", sizeof(buf)));
(gdb) bt
#0  HelloWorld () at test.h:10
#1  0x00000000004002e1 in main () at test1.cc:7
(gdb) si
HelloWorld () at test.h:8
8       inline void HelloWorld() {
(gdb) bt
#0  HelloWorld () at test.h:8
#1  0x00007fffffffdaa0 in ?? ()
#2  0x00000000004002e1 in main () at test1.cc:7
(gdb) si
0x0000000000400302      8       inline void HelloWorld() {
(gdb) bt
#0  0x0000000000400302 in HelloWorld () at test.h:8
#1  0x00007fffffffdaa0 in ?? ()
#2  0x00000000004002e1 in main () at test1.cc:7
(gdb) si
0x0000000000400307 in HelloWorld () at test.h:10
10        printf("memcmp(): %d\n", __builtin_memcmp(buf, "abc", sizeof(buf)));
(gdb) bt
#0  0x0000000000400307 in HelloWorld () at test.h:10
#1  0x00000000004002e1 in main () at test1.cc:7


Second, debug info differences:
readelf -w 

 <1><223>: Abbrev Number: 7 (DW_TAG_subprogram)
  <224>     DW_AT_external    : 1       
  <225>     DW_AT_name        : HelloWorld      
  <230>     DW_AT_decl_file   : 1       
  <231>     DW_AT_decl_line   : 8       
  <232>     DW_AT_MIPS_linkage_name: _Z10HelloWorldv    
  <242>     DW_AT_low_pc      : 0x4002fe        
  <24a>     DW_AT_high_pc     : 0x40033f        
  <252>     DW_AT_frame_base  : 0x4c    (location list)
...

 <1><36a>: Abbrev Number: 13 (DW_TAG_subprogram)
  <36b>     DW_AT_external    : 1       
  <36c>     DW_AT_name        : (indirect string, offset: 0x28): HelloWorld     
  <370>     DW_AT_decl_file   : 2       
  <371>     DW_AT_decl_line   : 8       
  <372>     DW_AT_MIPS_linkage_name: (indirect string, offset: 0xd5):
_Z10HelloWorldv   
  <376>     DW_AT_low_pc      : 0x4002fe        
  <37e>     DW_AT_high_pc     : 0x400343        
  <386>     DW_AT_frame_base  : 0x107   (location list)


Is HelloWorld spanning [0x4002fe,0x40033f] or [0x4002fe,0x400343] range?

Finally, GNU ld doesn't show the same problem: it zeros out debug* and
eh_frame entries corresponding to discarded sections:

000000d8 0000001c 00000090 FDE cie=00000090 pc=00000000..00000045
  DW_CFA_advance_loc4: 5 to 00000005
  DW_CFA_def_cfa_offset: 16
  DW_CFA_nop

And the debug info like this:

 <1><35d>: Abbrev Number: 12 (DW_TAG_subprogram)
  <35e>     DW_AT_external    : 1       
  <35f>     DW_AT_name        : foo     
  <363>     DW_AT_decl_file   : 2       
  <364>     DW_AT_decl_line   : 3       
  <365>     DW_AT_type        : <2dd>   
  <369>     DW_AT_inline      : 3       (declared as inline and inlined)
 <1><36a>: Abbrev Number: 13 (DW_TAG_subprogram)
  <36b>     DW_AT_external    : 1       
  <36c>     DW_AT_name        : (indirect string, offset: 0xb1): HelloWorld     
  <370>     DW_AT_decl_file   : 2       
  <371>     DW_AT_decl_line   : 8       
  <372>     DW_AT_MIPS_linkage_name: (indirect string, offset: 0x11d):
_Z10HelloWorldv  
  <376>     DW_AT_low_pc      : 0       
  <37e>     DW_AT_high_pc     : 0       
  <386>     DW_AT_frame_base  : 0x107   (location list)

-- 
           Summary: Gold produces incorrect debug and unwind info when
                    incompatible COMDAT sections are present
           Product: binutils
           Version: 2.20 (HEAD)
            Status: NEW
          Severity: normal
          Priority: P2
         Component: gold
        AssignedTo: ppluzhnikov at google dot com
        ReportedBy: ppluzhnikov at google dot com
                CC: bug-binutils at gnu dot org
 GCC build triplet: x86_64-unknown-linux-gnu
  GCC host triplet: x86_64-unknown-linux-gnu
GCC target triplet: x86_64-unknown-linux-gnu


http://sourceware.org/bugzilla/show_bug.cgi?id=10400

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]