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]

exit() and __cxa_atexit()


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]