[patch] __call_atexit.c: Fix __call_exitprocs.
Kazu Hirata
kazu@codesourcery.com
Thu Apr 5 13:59:00 GMT 2007
Hi,
Attached is a patch to fix __call_exitprocs, which in turn fixes
failures of g++.old-deja/g++.other/init18.C and
g++.old-deja/g++.other/init19.C in the g++ testsuite.
Here is a description from Mark Mitchell.
The init19.C failures we're seeing with GCC 4.2 on newlib targets
are in fact a bug in newlib. The test case is calling "atexit" from
within a function that is itself an "atexit" function; in other
words, we call exit, which calls the first atexit function, which
then registers a second atexit function. The second atexit function
was never being called by newlib. The C99 standard does imply that
the library should handle this case:
First, all functions registered by the atexit function are called,
in the reverse order of their registration, except that a function
is called after any previously registered functions that had been
called at the time it was registered.
That last clause says that the second atexit function above is
called after the first one, even though the first one was registered
first.
Tested on fido-none-elf and m68k-elf. OK to apply?
Kazu Hirata
newlib/
2007-04-04 Mark Mitchell <mark@codesourcery.com>
* libc/stdlib/__call_atexit.c (__call_exitprocs): Handle atexit
functions registering additional atexit functions.
Index: newlib/libc/stdlib/__call_atexit.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdlib/__call_atexit.c,v
retrieving revision 1.4
diff -u -d -p -r1.4 __call_atexit.c
--- newlib/libc/stdlib/__call_atexit.c 21 Mar 2006 00:57:34 -0000 1.4
+++ newlib/libc/stdlib/__call_atexit.c 5 Apr 2007 03:17:23 -0000
@@ -23,6 +23,8 @@ _DEFUN (__call_exitprocs, (code, d),
int i;
void (*fn) (void);
+ restart:
+
p = _GLOBAL_REENT->_atexit;
lastp = &_GLOBAL_REENT->_atexit;
while (p)
@@ -34,6 +36,8 @@ _DEFUN (__call_exitprocs, (code, d),
#endif
for (n = p->_ind - 1; n >= 0; n--)
{
+ int ind;
+
i = 1 << n;
/* Skip functions not from this dso. */
@@ -52,6 +56,8 @@ _DEFUN (__call_exitprocs, (code, d),
if (!fn)
continue;
+ ind = p->_ind;
+
/* Call the function. */
if (!args || (args->_fntypes & i) == 0)
fn ();
@@ -59,6 +65,12 @@ _DEFUN (__call_exitprocs, (code, d),
(*((void (*)(int, _PTR)) fn))(code, args->_fnargs[n]);
else
(*((void (*)(_PTR)) fn))(args->_fnargs[n]);
+
+ /* The function we called called atexit and registered another
+ function (or functions). Call these new functions before
+ continuing with the already registered fucntions. */
+ if (ind != p->_ind || *lastp != p)
+ goto restart;
}
#ifndef _ATEXIT_DYNAMIC_ALLOC
More information about the Newlib
mailing list