[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: fix for atexit() bug in glibc 2.2.3
From: |
Franz Sirl |
Subject: |
Re: fix for atexit() bug in glibc 2.2.3 |
Date: |
Sun, 20 May 2001 13:55:21 +0200 |
The patch for the gcc-2_95-branch (including other stuff) is at
<ftp://devel.linuxppc.org/users/fsirl/>
and should fix this problem.
Bernd, can you commit the minimum patch I applied to the mainline and the
3.0 branch to the gcc-2_95-branch? This should do it for now (the glibc case)
and we can talk about refinements after my vacation.
Franz.
On Sunday 20 May 2001 09:52, Andreas Jaeger wrote:
> Hi Mark and Franz, FYI: it seems that even gcc 2.95.3 on i686 miscompiles
> weak symbols.
>
> Andreas, this is a compiler bug you encounter. Franz has some patches
> to fix this and I hope he'll point you to them, otherwise search the
> GCC mailing list archives.
>
> Andreas
>
> Andreas Steinmetz <address@hidden> writes:
> > Unfortunately applying your patch to gcc and rebuilding gcc-2.95.3, then
> > glibc-2.2.3, doesn't fix the atexit() sigsegv problem for statically
> > linked programs. So I started digging myself. Looking at atexit() in a
> > statically linked test progam:
> >
> > 0x80485d0 <atexit>: sub $0xc,%esp
> > 0x80485d3 <atexit+3>: mov $0x0,%edx
> > 0x80485d8 <atexit+8>: mov 0x10(%esp,1),%ecx
> > 0x80485dc <atexit+12>: xor %eax,%eax
> > 0x80485de <atexit+14>: add $0xfffffffc,%esp
> > 0x80485e1 <atexit+17>: test %edx,%edx
> > 0x80485e3 <atexit+19>: cmovne 0x0,%eax <========= SIGSEGV
> > 0x80485ea <atexit+26>: push %eax
> > 0x80485eb <atexit+27>: push $0x0
> > 0x80485ed <atexit+29>: push %ecx
> > 0x80485ee <atexit+30>: call 0x80486e0 <__cxa_atexit>
> > 0x80485f3 <atexit+35>: add $0x10,%esp
> > 0x80485f6 <atexit+38>: add $0xc,%esp
> > 0x80485f9 <atexit+41>: ret
> >
> > Registers at SIGSEGV time:
> >
> > eax 0x0 0
> > ecx 0x8048210 134513168
> > edx 0x0 0
> > ebx 0xbffff9ac -1073743444
> > esp 0xbffff910 0xbffff910
> > ebp 0xbffff93c 0xbffff93c
> > esi 0xbffff9a4 -1073743452
> > edi 0x1 1
> > eip 0x80485e3 0x80485e3
> > eflags 0x10346 66374
> > cs 0x23 35
> > ss 0x2b 43
> > ds 0x2b 43
> > es 0x2b 43
> > fs 0x0 0
> > gs 0x0 0
> > fctrl 0x37f 895
> > fstat 0x0 0
> > ftag 0xffff 65535
> > fiseg 0x10 16
> > fioff 0xc03121bf -1070521921
> > foseg 0x0 0
> > fooff 0x0 0
> > fop 0x4f1 1265
> >
> > Well, I don't have an assembler manual around so I can't tell if the
> > access to the source by cmovne is defined as standard or if it is just an
> > unexpected speculative access (I'm running an Athlon TB900). One would
> > expect, however, that a conditional move data access would only happen if
> > the condition is met which it is not (edx=0).
> >
> > The same in the source (stdlib/atexit.c):
> >
> > /* This is defined by newer gcc version unique for each module. */
> > extern void *__dso_handle __attribute__ ((__weak__));
> >
> >
> > /* Register FUNC to be executed by `exit'. */
> > int
> > atexit (void (*func) (void))
> > {
> > return __cxa_atexit ((void (*) (void *)) func, NULL,
> > &__dso_handle == NULL ? NULL : __dso_handle);
> > } ^^
> >
> > This being the problem
> >
> >
> > As it turns out a workaround is simple (de-optimization, patch below):
> >
> > =======snip=======
> > --- stdlib/atexit.c-2.2.3 Sat May 19 20:13:37 2001
> > +++ stdlib/atexit.c Sat May 19 20:48:51 2001
> > @@ -28,8 +28,9 @@
> > int
> > atexit (void (*func) (void))
> > {
> > - return __cxa_atexit ((void (*) (void *)) func, NULL,
> > - &__dso_handle == NULL ? NULL : __dso_handle);
> > + if(&__dso_handle)return __cxa_atexit ((void (*) (void *)) func,
> > + NULL,__dso_handle);
> > + else return __cxa_atexit ((void (*) (void *)) func, NULL,NULL);
> > }
> >
> > /* Hide the symbol so that no definition but the one locally in the
> > ======snip========
> >
> > This results in the following assembler which is 'bug free':
> >
> > 0x80485d0 <atexit>: sub $0xc,%esp
> > 0x80485d3 <atexit+3>: mov $0x0,%eax
> > 0x80485d8 <atexit+8>: mov 0x10(%esp,1),%edx
> > 0x80485dc <atexit+12>: test %eax,%eax
> > 0x80485de <atexit+14>: je 0x80485ec <atexit+28>
> > 0x80485e0 <atexit+16>: add $0xfffffffc,%esp
> > 0x80485e3 <atexit+19>: mov 0x0,%eax
> > 0x80485e8 <atexit+24>: push %eax
> > 0x80485e9 <atexit+25>: jmp 0x80485f1 <atexit+33>
> > 0x80485eb <atexit+27>: nop
> > 0x80485ec <atexit+28>: add $0xfffffffc,%esp
> > 0x80485ef <atexit+31>: push $0x0
> > 0x80485f1 <atexit+33>: push $0x0
> > 0x80485f3 <atexit+35>: push %edx
> > 0x80485f4 <atexit+36>: call 0x80486e0 <__cxa_atexit>
> > 0x80485f9 <atexit+41>: add $0x10,%esp
> > 0x80485fc <atexit+44>: add $0xc,%esp
> > 0x80485ff <atexit+47>: ret
> >
> > I don't really know if the actual bug is caused by glibc-2.2.3 or
> > gcc-2.95.3. This problem should be solved, however, by the appropriate
> > party (please forward this mail to the proper developers, if necessary).
> > Furthermore '__dso_handle' is used in more places, especially
> > 'malloc/mtrace.c'. So further fixes may be required.
> >
> > To better check for the problem here's the configure statement (oh,
> > configure needs to be modified to be able to not build against libgd even
> > when it is around, I patched that the hard way...) and the compiler
> > flags:
> >
> > ../configure --prefix=/usr --enable-add-ons --disable-profile
> > --enable-kernel=2.2.18 --with-headers=/usr/src/linux/include
> > --without-gmp --without-gd --without-gd-include --without-gd-lib
> > --without-cvs --with-elf --enable-shared
> >
> > CFLAGS=-O3 -fomit-frame-pointer -funroll-loops -fexpensive-optimizations
> > -fschedule-insns2 -mwide-multiply -march=pentiumpro -mcpu=pentiumpro
> > -malign-loops=2 -malign-jumps=2 -malign-functions=4
> >
> > CXXFLAGS=-O3 -fomit-frame-pointer -funroll-loops
> > -fexpensive-optimizations -fschedule-insns2 -mwide-multiply
> > -march=pentiumpro -mcpu=pentiumpro -malign-loops=2 -malign-jumps=2
> > -malign-functions=4
> >
> > When I'm at it: 'make check' uses somewhere a hardcoded '/bin/cat' which
> > is not nice if cat is not in /bin. 'make install' doesn't honor a
> > softlink for '/etc/ld.so.cache' but replaces the softlink with a new
> > cache file.
> >
> > On 16-May-2001 Andreas Jaeger wrote:
> > > Andreas Steinmetz <address@hidden> writes:
> > >> Hi,
> > >> when building static (-static) versions of fileutils-4.1 with gcc
> > >> 2.95.3 the resulting binaries segfault in atexit(). Temporary fix for
> > >> me is an atexit() shim diverting the call to on_exit().
> > >
> > > Did you apply the appended patch to GCC 2.95.3 as mentioned in the
> > > release notes?
> > >
> > >> After the upgrade from 2.2.2 to 2.2.3 the following packages stopped
> > >> working and had to be rebuilt against the new library:
> > >>
> > >> ypserv-1.3.12
> > >> nfs-utils-0.3.1 (rpc.kstatd)
> > >
> > > Really?
> > >
> > >> Installing glibc-2.2.3 did cause problems too:
> > >>
> > >> [snip]
> > >>
> > >> make -C linuxthreads subdir_install
> > >> make[2]: Entering directory `/usr/src/glibc-2.2.3/linuxthreads'
> > >> /bin/install -c -m 644 ../linuxthreads/sysdeps/pthread/pthread.h
> > >> /usr/include/pt/bin/install -c -m 644 semaphore.h
> > >> /usr/include/semaphore.h /bin/install -c
> > >> /usr/src/glibc-2.2.3/build/linuxthreads/libpthread.so
> > >> /lib/libpthread-0.9.so.new
> > >> mv -f /lib/libpthread-0.9.so.new /lib/libpthread-0.9.so
> > >> echo libpthread-0.9.so /lib/libpthread.so.0 >>
> > >> /usr/src/glibc-2.2.3/build/elf/symlink.list
> > >> rm -f /usr/lib/libpthread.so.new
> > >> /bin/sh ../scripts/rellns-sh /lib/libpthread.so.0
> > >> /usr/lib/libpthread.so.new mv -f /usr/lib/libpthread.so.new
> > >> /usr/lib/libpthread.so
> > >> /bin/install -c -m 644
> > >> /usr/src/glibc-2.2.3/build/linuxthreads/libpthread.a
> > >> /usr/lib/libpthread.a
> > >>
> > >> : /usr/lib/libpthread.a
> > >>
> > >> make[2]: Leaving directory `/usr/src/glibc-2.2.3/linuxthreads'
> > >> make -C resolv subdir_install
> > >> make: /lib/libc.so.6: version `GLIBC_2.2.3' not found (required by
> > >> /lib/libpthread.so.0)
> > >> make[1]: *** [resolv/subdir_install] Error 1
> > >> make[1]: Leaving directory `/usr/src/glibc-2.2.3'
> > >> make: *** [install] Error 2
> > >>
> > >> This happens as (at least my) make (make-3.79.1) is linked against
> > >> libpthread.so.0 which is installed before the symbolic link
> > >> /lib/libc.so.6 is
> > >> set up to point to the new glibc. Workaround is to use a statically
> > >> linked make
> > >> during installation (if you have one available).
> > >
> > > I'll forward this,
> > > Andreas
> > >
> > >
> > > P.S. see http://gcc.gnu.org/ml/gcc-patches/2001-03/msg01187.html
> > >
> > > 2001-03-16 Jakub Jelinek <address@hidden>
> > >
> > > * crtstuff.c (init_dummy): Use CRT_END_INIT_DUMMY if defined.
> > > Remove ia32 linux PIC kludge and move it...
> > > * config/i386/linux.h (CRT_END_INIT_DUMMY): ...here.
> > >
> > > --- gcc/config/i386/linux.h.jj Mon Mar 12 11:45:15 2001
> > > +++ gcc/config/i386/linux.h Fri Mar 16 18:52:31 2001
> > > @@ -170,3 +170,21 @@ Boston, MA 02111-1307, USA. */
> > > }
> > > \ } while (0)
> > > #endif
> > > +
> > > +#if defined(__PIC__) && defined (USE_GNULIBC_1)
> > > +/* This is a kludge. The i386 GNU/Linux dynamic linker needs
> > > ___brk_addr, + __environ and atexit (). We have to make sure they are
> > > in the .dynsym + section. We accomplish it by making a dummy call
> > > here. This + code is never reached. */
> > > +
> > > +#define CRT_END_INIT_DUMMY \
> > > + do \
> > > + { \
> > > + extern void *___brk_addr; \
> > > + extern char **__environ; \
> > > + \
> > > + ___brk_addr = __environ; \
> > > + atexit (0); \
> > > + } \
> > > + while (0)
> > > +#endif
> > > ============================================================
> > > Index: gcc/crtstuff.c
> > > --- gcc/crtstuff.c 1999/03/23 00:43:51 1.18
> > > +++ gcc/crtstuff.c 2001/03/19 10:21:44
> > > @@ -379,20 +379,8 @@
> > > FORCE_INIT_SECTION_ALIGN;
> > > #endif
> > > asm (TEXT_SECTION_ASM_OP);
> > > -
> > > -/* This is a kludge. The i386 GNU/Linux dynamic linker needs
> > > ___brk_addr, - __environ and atexit (). We have to make sure they are
> > > in the .dynsym - section. We accomplish it by making a dummy call
> > > here. This - code is never reached. */
> > > -
> > > -#if defined(__linux__) && defined(__PIC__) && defined(__i386__)
> > > - {
> > > - extern void *___brk_addr;
> > > - extern char **__environ;
> > > -
> > > - ___brk_addr = __environ;
> > > - atexit ();
> > > - }
> > > +#ifdef CRT_END_INIT_DUMMY
> > > + CRT_END_INIT_DUMMY;
> > > #endif
> > > }
> > >
> > >
> > >
> > > --
> > > Andreas Jaeger
> > > SuSE Labs address@hidden
> > > private address@hidden
> > > http://www.suse.de/~aj
> >
> > Andreas Steinmetz
> > D.O.M. Datenverarbeitung GmbH