public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/16007] New: Use of static template members results in broken executables
@ 2004-06-15 16:59 kiwi at xtradyne dot de
  2004-06-15 17:12 ` [Bug c++/16007] " ian at wasabisystems dot com
                   ` (15 more replies)
  0 siblings, 16 replies; 17+ messages in thread
From: kiwi at xtradyne dot de @ 2004-06-15 16:59 UTC (permalink / raw)
  To: gcc-bugs

Hi,

I think I discovered a bug in g++ which leads to misbehaviour in the runtime
system of Solaris. I am using binutils 2.14 and gcc-3.4.0 on Solaris 8.

When I link an executable using libthread.so with code containing at least one
static template member, I get an exception from my thread abstraction library
which is triggered by uninitialized data accessed by libthread.

Intense debugging revealed that libthread is using memory obtained with a call
to sbrk which should be all zeroes and it relies on the memory being zeroed.

If the code is linked with code having static template members, the memory
returned by sbrk is not zeroes, but contains the content of the sections
following the .bss in the executable. I was able to find the content of the
sections .comment and .stabs.indexstr in the memory area directly following the
.bss segment (in memory of the just started process).

Further investigation revealed that the reason for the "dirt" being in the
memory is that the executable contains a section .bss as follows

21 .bss          00000100  000479c8  000479c8  000279c8  2**3
                 CONTENTS, ALLOC, LOAD, DATA

whereas in the correct case (no "dirt" following the .bss section in memory)

21 .bss          000000f8  0002b328  0002b328  0000b328  2**3
                 ALLOC

The "dirt" case seems to be triggered by the presence of static template members
in one of the linked object files. A static template member is shown as follows
by objdump

511 .gnu.linkonce.b._ZN19InternalNotificatorI12ChangeRecordE14notificatorMapE
00000004  00000000  00000000  000533b8  2**2
                 CONTENTS, ALLOC, LOAD, DATA, LINK_ONCE_DISCARD

This obviously makes the linker include a .bss section content and change the
flags for .bss from ALLOC to CONTENTS, ALLOC, LOAD, DATA. There are many other
gnu.linkonce.b.* elements, but those have either RELOC or READONLY (or both) as
additional flags. If the .bss section is marked CONTENTS, ALLOC, LOAD, DATA, the
program starter (ld.so probably) appends the content of the following sections
(.comment, .stabs.*) to the program in memory which in turn leads to the
described misbehaviour of libthread.so

I was able to circumvent the problem by writing a linker script which puts all
of .gnu.linkonce.b.* into a section other than .bss (the default linker script
includes .gnu.linkonce.b.* into .bss). When using the linker script, .bss has
ALLOC and the extra section created for .gnu.linkonce.b.* is flagged CONTENTS,
ALLOC, LOAD, DATA.

Discussion with Ian Lance Taylor on the binutils bug list convinced me that it
is a compiler bug, because the .gnu.linkonce.b* sections should never contain
any data.
(As a side note: everything works when building the gcc with the platform
linker, because the Solaris linker puts every .gnu.linkonce.b* section in its
own section in the resulting executable, not disturbing the .bss in any way)

Anyway, the behaviour of the Solaris program starter seems to be buggy also.
Even if the .bss section is present as loadable data, it should not make the
program loader append the contents of debugging sections to the loaded program
in memory.

How to reproduce (actually, the bug might go unnoticed in many cases as the
"dirt" following the executable's end only disturbs if the first caller(s) to
sbrk expect the memory returned to be zero-initialised. If they zero out the
memory before using it, everything will work fine. libthread.so zeroes out most
of it except some values vital for its operation). To test if the executable has
the problem, run objdump -x on it and look at the attributes for .bss. If they
are not ALLOC but CONTENTS, ALLOC, LOAD, DATA, LINK_ONCE_DISCARD the problem occurs.

I use a static member in a template as follows:


template<class ParamType = bool>
class InternalNotificator {

   static map<notificationTypes, InternalNotificator<ParamType> * > *
notificatorMap;

   ...
};

template<class ParamType>
map<notificationTypes, InternalNotificator<ParamType> * > *
InternalNotificator<ParamType>::notificatorMap;


this is assembled by the compiler (g++ 3.4.0) to

       .weak   _ZN19InternalNotificatorI12ChangeRecordE14notificatorMapE
       .section       
".gnu.linkonce.b._ZN19InternalNotificatorI12ChangeRecordE14notificatorMapE",#alloc,#write
       .align 4
       .type   _ZN19InternalNotificatorI12ChangeRecordE14notificatorMapE, #object
       .size   _ZN19InternalNotificatorI12ChangeRecordE14notificatorMapE, 4
_ZN19InternalNotificatorI12ChangeRecordE14notificatorMapE:
       .skip 4


g++ calls the gnu assembler:

/net/solaris/binutils-2.14/bin/as -V -Qy -s -K PIC -xarch=v8 -o StateMonitor.o
/var/tmp//ccOI4Yi1.s
GNU assembler version 2.14 (sparc-sun-solaris2.8) using BFD version 2.14 20030612

and finally objdump sees this as

511 .gnu.linkonce.b._ZN19InternalNotificatorI12ChangeRecordE14notificatorMapE
00000004  00000000  00000000  000533b8  2**2
                 CONTENTS, ALLOC, LOAD, DATA, LINK_ONCE_DISCARD

and elfdump shows this as

Section Header[511]:  sh_name:
.gnu.linkonce.b._ZN19InternalNotificatorI12ChangeRecordE14notificatorMapE
   sh_addr:      0               sh_flags:   [ SHF_WRITE  SHF_ALLOC ]
   sh_size:      0x4             sh_type:    [ SHT_PROGBITS ]
   sh_offset:    0x68398         sh_entsize: 0
   sh_link:      0               sh_info:    0
   sh_addralign: 0x4


Another note: the problem does not exist on Linux. There, the .bss is ALLOC,
even when an object file with the static template member is linked in.
This is the compiler output on Linux (same g++ 3.4.0)

       .weak   _ZN19InternalNotificatorI12ChangeRecordE14notificatorMapE
       .section       
.gnu.linkonce.b._ZN19InternalNotificatorI12ChangeRecordE14notificatorMapE,"aw",@nobits
       .align 4
       .type   _ZN19InternalNotificatorI12ChangeRecordE14notificatorMapE, @object
       .size   _ZN19InternalNotificatorI12ChangeRecordE14notificatorMapE, 4
_ZN19InternalNotificatorI12ChangeRecordE14notificatorMapE:
       .zero   4

Regards,

Axel Habermann

-- 
           Summary: Use of static template members results in broken
                    executables
           Product: gcc
           Version: 3.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: kiwi at xtradyne dot de
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: sparc-sun-solaris2.8
  GCC host triplet: sparc-sun-solaris2.8
GCC target triplet: sparc-sun-solaris2.8


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16007


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2005-05-31 16:37 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-06-15 16:59 [Bug c++/16007] New: Use of static template members results in broken executables kiwi at xtradyne dot de
2004-06-15 17:12 ` [Bug c++/16007] " ian at wasabisystems dot com
2004-06-15 17:13 ` ian at wasabisystems dot com
2004-06-15 17:41 ` ebotcazou at gcc dot gnu dot org
2004-06-19 12:15 ` ebotcazou at gcc dot gnu dot org
2004-07-07 10:57 ` ebotcazou at gcc dot gnu dot org
2004-07-07 13:35 ` [Bug target/16007] " ebotcazou at gcc dot gnu dot org
2004-07-13  3:28 ` ian at wasabisystems dot com
2004-08-29 19:09 ` mmitchel at gcc dot gnu dot org
2004-09-07 14:09 ` ebotcazou at gcc dot gnu dot org
2004-10-06 11:01 ` cvs-commit at gcc dot gnu dot org
2004-10-06 11:06 ` cvs-commit at gcc dot gnu dot org
2004-10-06 11:10 ` cvs-commit at gcc dot gnu dot org
2004-10-06 11:13 ` ebotcazou at gcc dot gnu dot org
2004-11-01  0:45 ` mmitchel at gcc dot gnu dot org
2004-12-07  0:30 ` pinskia at gcc dot gnu dot org
2005-05-31 16:38 ` ebotcazou at gcc dot gnu dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).