[RFC] Cygwin libstdc++ plan (operator new/delete replacement)

Dave Korn dave.korn.cygwin@googlemail.com
Fri Oct 2 05:38:00 GMT 2009


Christopher Faylor wrote:

> I don't see how you can remove the cygwin_external call as long as there
> are dlls out there which reset this field in cygwin_crt0.cc.  You just
> need one problem dll and this causes all sorts of bad problems when
> loading other dlls.

  But they call cygwin_external first, then fudge the pointer after that; so
the hack in cygwin_external won't have a chance to restore the pointer until
the *next* dll gets started up and calls cygwin_external, or maybe not at all
if it's not a dll but the exe getting started.  That's why you had to add
another reset in dll_crt0_1, and the missing part of the puzzle is that we
should also be doing so in dll_dllcrt0_1, where I left a loooong comment about
this earlier.

>   /* Broken DLLs built against Cygwin versions 1.7.0-49 up to 1.7.0-57
>      override the cxx_malloc pointer in their DLL initialization code,
>      when loaded either statically or dynamically.  Because this leaves
>      a stale pointer into demapped memory space if the DLL is unloaded
>      by a call to dlclose, we prevent this happening for dynamically
>      loaded DLLS in dlopen by saving and restoring cxx_malloc around
>      the call to LoadLibrary, which invokes the DLL's startup sequence.
>      Modern DLLs won't even attempt to override the pointer when loaded
>      statically, but will write their overrides directly into the
>      struct it points to.  With all modern DLLs, this will remain the
>      default_cygwin_cxx_malloc struct in cxx.cc, but if any broken DLLs
>      are in the mix they will have overridden the pointer and subsequent
>      overrides will go into their embedded cxx_malloc structs.  This is
>      almost certainly not a problem as they can never be unloaded, but
>      if we ever did want to do anything about it, we could check here to
>      see if the pointer had been altered in the early parts of the DLL's
>      startup, and if so copy back the new overrides and reset it here.
>      However, that's just a note for the record; at the moment, we can't
>      see any need to worry about this happening.  */

  We do in fact need to worry about it, because if the dll is from the faulty
zone 49-57 and redirects the malloc struct pointer to its own internal one,
and then the exe is pre-malloc stuff altogether and clears forkee at startup,
then by the time we get to your restore code we'll have lost sight of the fact
that there were a bunch of non-default overrides where the pointer got
redirected to altogether.  So I think what we need is for both dll_crt0_1 and
dll_dllcrt0_1 to execute a bit of code that looks like

  if (pointer is NULL)
     reset it to default cxx malloc
  else if (pointer doesn't point to default)
     copy entries from new pointer value into default struct
     and reset pointer to point to default.

  Anyway I really must sleep now.  More later.

    cheers,
      DaveK



More information about the Cygwin-developers mailing list