[patch] __call_atexit.c: Fix __call_exitprocs.

Kazu Hirata kazu@codesourcery.com
Thu Apr 5 13:59:00 GMT 2007


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

Tested on fido-none-elf and m68k-elf.  OK to apply?

Kazu Hirata

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),
       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)
+	  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]);
 	    (*((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;

More information about the Newlib mailing list