Index: dll_init.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/dll_init.cc,v retrieving revision 1.68 diff -p -u -r1.68 dll_init.cc --- dll_init.cc 29 Jan 2010 18:34:09 -0000 1.68 +++ dll_init.cc 1 Feb 2010 23:01:08 -0000 @@ -153,19 +153,27 @@ dll_list::alloc (HINSTANCE h, per_proces register an atexit function outside of the DLL and that should be run when the DLL detachs. */ static void -remove_dll_atexit (MEMORY_BASIC_INFORMATION& m) +remove_dll_atexit (const MEMORY_BASIC_INFORMATION& m) { - unsigned char *dll_beg = (unsigned char *) m.AllocationBase; - unsigned char *dll_end = (unsigned char *) m.AllocationBase + m.RegionSize; + unsigned char *dll_beg = (unsigned char *) m.BaseAddress; + unsigned char *dll_end = (unsigned char *) m.BaseAddress + m.RegionSize; struct _atexit *p = _GLOBAL_REENT->_atexit; - for (int n = p->_ind - 1; n >= 0; n--) - { - void (*fn) (void) = p->_fns[n]; - if ((unsigned char *) fn >= dll_beg && (unsigned char *) fn < dll_end) + + while (p) + { + for (int n = p->_ind - 1; n >= 0; n--) { - fn (); - p->_fns[n] = NULL; - } + void (*fn) (void) = p->_fns[n]; + if ((p->_on_exit_args._is_cxa & (1 << n)) == 0 + && (unsigned char *) fn >= dll_beg && (unsigned char *) fn < dll_end) + { + /* Remove the function now to protect against the + function calling exit recursively. */ + p->_fns[n] = NULL; + fn (); + } + } + p = p->_next; } }