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]

Re: Strange ld.gold segmentation error issues.


> ==4001==
> ==4001== Conditional jump or move depends on uninitialised value(s)
> ==4001==    at 0x4017777: strlen (rtld-strlen.S:65)
> ==4001==    by 0x40050BA: fillin_rpath (dl-load.c:492)
> ==4001==    by 0x4007C95: _dl_init_paths (dl-load.c:866)
> ==4001==    by 0x4002BB9: dl_main (rtld.c:1344)
> ==4001==    by 0x4015214: _dl_sysdep_start (dl-sysdep.c:249)
> ==4001==    by 0x40049F5: _dl_start (rtld.c:332)
> ==4001==    by 0x4001187: ??? (in /lib/x86_64-linux-gnu/ld-2.18.so)
> ==4001==    by 0x60: ???
> ==4001==    by 0xFFEFFF66E: ???
> ==4001==    by 0xFFEFFF67E: ???
> ==4001==    by 0xFFEFFF68A: ???
> ==4001==    by 0xFFEFFF695: ???
> ==4001==
> ==4001== Invalid read of size 1
> ==4001==    at 0x517240: gold::Gdb_index::add_symbol(int, char const*,
> unsigned char) (gdb-index.cc:164)

This memcheck output really isn't telling us anything new -- this is
right where the segfault is happening.

The object file you sent me does appear to have a problem, and the
gold linker isn't being careful enough to detect the corruption. The
problem is with the .debug_pubnames section:

  [11] .debug_pubnames   PROGBITS        0000000000000000 00023d
00041b 00      0   0  1

Note that its length is 0x41b (1051 bytes). readelf -wp shows this:

Contents of the .debug_pubnames section:

  Length:                              12506
  Version:                             2
  Offset into .debug_info section:     0x0
  Size of area in .debug_info section: 2522

    Offset Name
    242   PR_FAILURE
    24f   PR_SUCCESS
    289   IPPROTO_IP
    296   IPPROTO_HOPOPTS
    2a8   IPPROTO_ICMP
    ...

Note that the unit_length field is given as 12506 bytes. Gold should
have checked that the length given there was no larger than the number
of bytes remaining in the section, but doesn't, and it runs off the
end of the section, trying to add more names than there actually are
in the table. Under the wrong conditions, this could run off the end
of an mmap'ed region, which explains why it only sometimes crashes.

You weren't seeing this problem with older versions of gold because
the older versions would stop reading the pubnames table as soon as
they saw a pubnames table entry with a DIE offset == 0. But with
-gsplit-dwarf and -fdebug-types-sections, it's possible to have
pubnames table entries where we have no valid DIE offset to output, so
GCC outputs those entries with a 0 offset, and gold needs to keep on
reading, or it will fail to add all the names to the GDB index.

I'll commit a fix to gold that will prevent it from running past the
end of the section, and I'll look into the GCC bug (it may already
have been fixed in a more recent version of GCC).

By the way, for best results with split DWARF, I recommend using GCC
4.9, which generates more information in the pubnames tables (now
named .debug_gnu_pubnames/pubtypes). The extra information allows gold
to generate a better .gdb_index, which lets GDB run faster.

Thanks for taking the time to collect so much information about what's
going wrong! It helped quite a bit in tracking this down.

-cary


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