delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2010/02/23/23:35:00

X-Recipient: archive-cygwin AT delorie DOT com
X-SWARE-Spam-Status: No, hits=-2.5 required=5.0 tests=AWL,BAYES_00
X-Spam-Check-By: sourceware.org
Message-ID: <4B84B08C.7060302@gmail.com>
Date: Wed, 24 Feb 2010 04:52:28 +0000
From: Dave Korn <dave DOT korn DOT cygwin AT googlemail DOT com>
User-Agent: Thunderbird 2.0.0.17 (Windows/20080914)
MIME-Version: 1.0
To: Dave Korn <dave DOT korn DOT cygwin AT googlemail DOT com>
CC: cygwin AT cygwin DOT com
Subject: Re: Statically initialising pthread attributes in dynamic dlls.
References: <4B825D76 DOT 6000105 AT gmail DOT com> <4B82C093 DOT 7010001 AT gmail DOT com> <4B83A727 DOT 3030101 AT gmail DOT com> <4B841026 DOT 1000905 AT gmail DOT com> <20100224004403 DOT GA24591 AT ednor DOT casa DOT cgf DOT cx> <4B848353 DOT 2010209 AT gmail DOT com>
In-Reply-To: <4B848353.2010209@gmail.com>
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com

On 24/02/2010 01:39, Dave Korn wrote:
> On 24/02/2010 00:44, Christopher Faylor wrote:

>> Anyway, I've revisited this code, just like I knew I would, and have
>> added YA in a long series of tweaks which seems to fix your particular
>> problem.  The fix is in the latest snapshot.
> 
>   :( I think I can see where the next problem is going to arise already.
> 
>   If we move el to the front of the list each time, what's going to happen
> when we eventually return from LoadLibrary, and el.prev is still pointing at
> the now-deallocated stack frames where LoadLibrary created its temporary
> EXCEPTION_REGISTRATION structures ?

  Confirmed.  Here's the SEH chain at the call to pthread_mutexattr_init:

> (gdb) x/xw 0x7ffde000
> 0x7ffde000:     0x0022ce68
> (gdb) x/2xw 0x0022ce68
> 0x22ce68:       0x0022c8b4      0x61028d70
> (gdb) x/2xw 0x0022c8b4
> 0x22c8b4:       0x0022cb4c      0x77fb7e64
> (gdb) x/2xw 0x0022cb4c
> 0x22cb4c:       0x0022cbf8      0x77fb7e64
> (gdb) x/2xw 0x0022cbf8
> 0x22cbf8:       0x0022ffe0      0x7c5c2160
> (gdb) x/2xw 0x0022ffe0
> 0x22ffe0:       0xffffffff      0x7c5c2160
> (gdb) print $esp
> $1 = (void *) 0x22c764

  At this point, the call stack looks roughly like main -> dlopen ->
LoadLibraryW -> DllMain -> dll_dllcrt0_1 -> dll::init (because the cygwin dll
is already initialised, we don't defer calling) -> dll static ctors ->
Mutex::Mutex -> pthread_mutexattr_init.  After this, we return from the Mutex
ctor, dll::init calls DllMain and then returns back to the OS loader code
which eventually returns via the tail of LoadLibrary and dlopen to main:

> (gdb) c
> Continuing.
> 
> Breakpoint 6, main (argc=1, argv=0x659e18) at test.cpp:6
> 6         dlclose( dll );
> (gdb) print $esp
> $2 = (void *) 0x22cd00
> (gdb) x/xw 0x7ffde000
> 0x7ffde000:     0x0022ffe0
> (gdb) x/2xw 0x0022ffe0
> 0x22ffe0:       0xffffffff      0x7c5c2160
> (gdb)

  Our EH got uninstalled when the OS uninstalled its own handlers!  That makes
sense of course: when a function that has instantiated an
EXCEPTION_REGISTRATION record in automatic stack storage returns, it's just
going to assume that any deeper ones have already been unwound and look at its
own prev pointer and just set the head of the eh chain there.

  I think the answer lies here, in this comment in dll_dllcrt0_1:

>   /* Make sure that our exception handler is installed.
>      That should always be the case but this just makes sure.
> 
>      At some point, we may want to just remove this code since
>      the exception handler should be guaranteed to be installed.
>      I'm leaving it in until potentially after the release of
>      1.7.1 */
>   _my_tls.init_exception_handler (_cygtls::handle_exceptions);

  Well, it may or may not already be installed, depending whether we got here
via dlopen or whether this is a statically-linked DLL being initialised at
process startup, and if it is already installed, it's not at the front of the
list.  So I figure the best bet would be to replace this call with a local
stack-frame-based exception registration record, which we'll unlink if we
return.  IOW, just the same thing as those OS-registered SEH frames are doing
when they unwind.  I'll report back later if it works.

    cheers,
      DaveK


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019