This is the mail archive of the
cygwin-patches
mailing list for the Cygwin project.
Re: dlclose not calling destructors of static variables.
- From: Dave Korn <dave dot korn dot cygwin at googlemail dot com>
- To: Dave Korn <dave dot korn dot cygwin at googlemail dot com>
- Cc: cygwin-patches at cygwin dot com
- Date: Mon, 01 Feb 2010 23:21:34 +0000
- Subject: Re: dlclose not calling destructors of static variables.
- References: <4B62DDE6.5070106@gmail.com> <4B62F118.8010305@gmail.com> <20100129184514.GA9550@ednor.casa.cgf.cx> <4B66BF2F.4060802@gmail.com> <20100201162603.GB25374@ednor.casa.cgf.cx> <4B6710CE.40300@gmail.com> <20100201174611.GA26080@ednor.casa.cgf.cx> <20100201175123.GB26080@ednor.casa.cgf.cx> <4B672B74.4090808@gmail.com> <4B6736C1.8030101@gmail.com> <20100201215919.GA29662@ednor.casa.cgf.cx> <4B675776.4020105@gmail.com>
On 01/02/2010 22:36, Dave Korn wrote:
> On 01/02/2010 21:59, Christopher Faylor wrote:
>
>> Since the testcase (obviously?) worked for me it seems like this is pretty
>> variable. I'd like to understand why the MEMORY_BASIC_INFORMATION method
>> doesn't work before trying other things.
>
>
> Hmm, well first off, looks like RegionSize is indeed relative to
> BaseAddress, not AllocationBase after all:
This is what I'm going to test next. It avoids calling anything registered
with the cxa functions, i.e. only calls ordinary atexit hooks, and it handles
the case where extra atexit blocks have been chained on the end.
cheers,
DaveK
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;
}
}