exit() and __cxa_atexit()

Sebastian Huber sebastian.huber@embedded-brains.de
Thu Jul 11 12:56:00 GMT 2013


Hello,

I have some GCC test suite problems since the __cxa_atexit() on Newlib seem to 
produce unexpected results.  The GCC test suite has a program to detect the 
availability of __cxa_atexit() in file "gcc/testsuite/lib/target-supports.exp":

#include <stdlib.h>
static unsigned int count;
struct X
{
   X() { count = 1; }
   ~X()
   {
     if (count != 3)
       exit(1);
     count = 4;
   }
};
void f()
{
   static X x;
}
struct Y
{
   Y() { f(); count = 2; }
   ~Y()
   {
     if (count != 2)
       exit(1);
     count = 3;
   }
};
Y y;
int main() { return 0; }

If I run this program on Linux I get:

Breakpoint 3, Y::Y (this=0x601048) at test.cc:19
19                        Y() { f(); count = 2; }
(gdb) c
Continuing.

Breakpoint 2, X::X (this=0x601058) at test.cc:5
5                         X() { count = 1; }
(gdb)
Continuing.

Breakpoint 4, Y::~Y (this=0x601048, __in_chrg=<optimized out>) at test.cc:22
22                          if (count != 2)
(gdb)
Continuing.

Breakpoint 1, X::~X (this=0x601058, __in_chrg=<optimized out>) at test.cc:8
8                           if (count != 3)
(gdb)

If I run this program on RTEMS I get:

Breakpoint 5, Y::Y (this=0x41630 <y>) at test.cc:19
19                        Y() { f(); count = 2; }
(gdb) c
Continuing.

Breakpoint 3, X::X (this=0x41790 <f()::x>) at test.cc:5
5                         X() { count = 1; }
(gdb)
Continuing.

*** EXIT code 0

Breakpoint 4, X::~X (this=0x41790 <f()::x>, __in_chrg=<optimized out>) at test.cc:8
8                           if (count != 3)
(gdb)
Continuing.

*** EXIT code 1

Breakpoint 6, Y::~Y (this=0x41630 <y>, __in_chrg=<optimized out>) at test.cc:22
22                          if (count != 2)
(gdb)

On Linux the Y global object is destroyed BEFORE the X function static object, 
on Newlib it is AFTER.

The reason for this is the exit() implementation "libc/stdlib/exit.c":

void
_DEFUN (exit, (code),
	int code)
{
   __call_exitprocs (code, NULL);

   if (_GLOBAL_REENT->__cleanup)
     (*_GLOBAL_REENT->__cleanup) (_GLOBAL_REENT);
   _exit (code);
}

The __call_exitprocs() destroys the X function static object and _exit() 
destroys the Y global object.

Exists there a standard that specifies which behaviour is correct?

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.



More information about the Newlib mailing list