This is the mail archive of the cygwin-patches mailing list for the Cygwin 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]

Re: dlclose not calling destructors of static variables.


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;
     }
 }
 

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