[patch] __call_atexit.c: Fix __call_exitprocs.
Jeff Johnston
jjohnstn@redhat.com
Thu Apr 5 15:58:00 GMT 2007
Kazu Hirata wrote:
> 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?
>
Yes, please do. Just fix the typo below in the comment (functions
instead of fucntions).
Thanks,
-- Jeff J.
> 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