This is the mail archive of the newlib@sourceware.org mailing list for the newlib 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] |
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
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |