[Fwd: dlopen regression in 1.7? (or is it just me?)]

Corinna Vinschen corinna-cygwin@cygwin.com
Wed Aug 12 07:36:00 GMT 2009

On Aug 12 02:14, Dave Korn wrote:
> Corinna Vinschen wrote:
>   Yes, this is a real problem.  It's 2am over here; I'll get onto it in the
> morning.  Sorry for the inconvenience; I really didn't expect people to try to
> unload their override of a vital library function at runtime and still expect it
> to work!
> > AFAICS this mechanism can't work reliable for dynamically loaded DLLs
> > since they could be dlclosed at any given time.  There must be a
> > mechanism which works sort of like a linked list of cxx_malloc
> > structures.  And then again, how often is it allowed to override
> > the cxx_malloc pointers at all?  Is it really correct that any
> > arbitrary DLL can install another set of cxx_malloc methods?  I have
> > some doubts...
>   The golden rule, as far as the gABI (substitute cxx-abi, SysV ABI; they are
> all inter-related and descended from each other) is concerned, is that the sum
> total of an exe + loaded DSOs should behave exactly the same as the equivalent
> statically-linked program.
>   That is obviously underspecified w.r.t. dlclose(), as there's no equivalent
> concept in a statically-linked exe to "part of your code suddenly disappears".
> So I don't think there should even _be_ a malloc override in a library that's
> liable to be dlclosed at runtime; it's really wrong to temporarily load or
> prematurely unload something that overrides one of the vital malloc operators,
> and I don't suppose it works well on Linux either.  If it does have some way of
> avoiding this problem we could probably adopt it, otherwise I imagine I need to
> add some kind of malloc override deregistration routine to go alongside the way
> they all register their overrides at startup.
>   Anyway, as I said it's 2am and I plan to get back onto a regular day/night
> schedule tonight, so I'll look at this in the morning.  Thanks for the heads-up.


The real ugly problem is that this code is not part of Cygwin, but is
part of the DLL startup code linked in statically from libcygwin.a.
That means, every DLL linked against Cygwin-1.7.0-49 and later (since
back to 2009-06-08), which is potentially dlopened and dlclosed, has to
be rebuild.

[...time passes...]

Of course, we could also kludge dlopen to workaround "broken" DLLs.
It could store the old cxx_malloc pointer before calling LoadLibrary and 
restore it afterwards.  This would allow us to stick with these DLLs.

I tested the below patch to dlopen.  It seems to work nicely for the
testcase sent by Peter.  Any drawbacks?

Index: dlfcn.cc
RCS file: /cvs/src/src/winsup/cygwin/dlfcn.cc,v
retrieving revision 1.41
diff -u -p -r1.41 dlfcn.cc
--- dlfcn.cc	16 Apr 2009 16:17:58 -0000	1.41
+++ dlfcn.cc	12 Aug 2009 07:36:08 -0000
@@ -93,7 +93,23 @@ dlopen (const char *name, int)
 	  wchar_t *path = tp.w_get ();
 	  pc.get_wide_win32_path (path);
+	  /* Workaround for broken DLLs built against Cygwin versions 1.7.0-49
+	     up to 1.7.0-57.  They override the cxx_malloc pointer in their
+	     DLL initialization code even if loaded dynamically.  This is a
+	     no-no since a later dlclose lets cxx_malloc point into nirvana.
+	     The below kludge "fixes" that by reverting the original cxx_malloc
+	     pointer after LoadLibrary. */
+	  /* Store original cxx_malloc pointer. */
+	  struct per_process_cxx_malloc *tmp_malloc;
+	  tmp_malloc = __cygwin_user_data.cxx_malloc;
 	  ret = (void *) LoadLibraryW (path);
+	  /* Restore original cxx_malloc pointer. */
+	  __cygwin_user_data.cxx_malloc = tmp_malloc;
 	  if (ret == NULL)
 	    __seterrno ();


Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

More information about the Cygwin-developers mailing list