[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