If _DL_FINI_CRT_COMPAT is defined, _dl_fini is setup to run at exit via atexit(), but this makes it run _before_ the fini (__app_fini()) of the app, causing stuff like sandbox that frees structs, etc via its fini to segfault. Relevant back-trace: (gdb) bt #0 0x400cb62c in free () from /lib/libc.so.0 #1 0x4000b3da in before_syscall (func=0x4000bd63 "unlink", file=0x80dca90 "/tmp/groff35k2OB") at libsandbox.c:1362 #2 0x40009c28 in unlink (pathname=0x80dca90 "/tmp/groff35k2OB") at libsandbox.c:657 #3 0x0805e34c in xtmpfile_list_init::~xtmpfile_list_init () #4 0x0805e557 in __static_initialization_and_destruction_0 () #5 0x0805e5a8 in global destructors keyed to tmpfile_prefix () #6 0x080494d6 in __do_global_dtors_aux () #7 0x0805e5fc in _fini () #8 0x400c91ba in exit () from /lib/libc.so.0 #9 0x400a1f7d in __uClibc_start_main () from /lib/libc.so.0 #10 0x080494a8 in _start () #11 0x00000003 in ?? () #12 0xbffff744 in ?? () #13 0xbffff754 in ?? () #14 0x08048ff8 in ?? () #15 0x0805e5e8 in __do_global_ctors_aux () #16 0x00000000 in ?? () --- uClibc-0.9.28/libc/misc/internals/__uClibc_main.c 2005-09-06 20:15:11 +0000 +++ uClibc-0.9.28.az/libc/misc/internals/__uClibc_main.c 2005-09-06 20:48:16 +0000 @@ -160,6 +160,16 @@ void attribute_hidden (*__rtld_fini)(void) = NULL; +#ifdef _DL_FINI_CRT_COMPAT +void attribute_hidden (*__dl_fini)(void) = NULL; + +void _set__dl_fini(void *fini_func) +{ + if (fini_func != NULL) + __dl_fini = fini_func; +} +#endif + /* __uClibc_start_main is the new main stub for uClibc. This function is * called from crt0 (version 0.9.16 or newer), after ALL shared libraries * are initialized, just before we call the application's main function. --- uClibc-0.9.28/ldso/ldso/ldso.c 2005-09-06 20:12:30 +0000 +++ uClibc-0.9.28.az/ldso/ldso/ldso.c 2005-09-06 20:57:28 +0000 @@ -766,11 +766,13 @@ #ifdef _DL_FINI_CRT_COMPAT /* arches that have moved their ldso FINI handling should skip this part */ { - int (*_dl_atexit) (void *) = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit", + void (*__set__dl_fini) (void *) = (void (*)(void *)) (intptr_t) _dl_find_hash("_set__dl_fini", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT); - if (_dl_atexit) - (*_dl_atexit) (_dl_fini); + if (__set__dl_fini) + (__set__dl_fini)(_dl_fini); + else + _dl_if_debug_dprint("_set__dl_fini not found\n"); } #endif --- uClibc-0.9.28/libc/stdlib/atexit.c 2005-09-06 19:57:44 +0000 +++ uClibc-0.9.28.az/libc/stdlib/atexit.c 2005-09-06 20:45:22 +0000 @@ -223,6 +222,11 @@ #endif extern void (*__rtld_fini)(void); + +#ifdef _DL_FINI_CRT_COMPAT +extern void (*__dl_fini)(void); +#endif + /* * Normal program termination */ @@ -242,6 +246,9 @@ #ifndef _DL_FINI_CRT_COMPAT if (__rtld_fini != NULL) (__rtld_fini)(); +#else + if (__dl_fini != NULL) + (__dl_fini)(); #endif /* If we are using stdio, try to shut it down. At the very least,