On 24/02/2010 04:52, Dave Korn wrote: > 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.
Yeh, that works nicely. Here's what I tested, along with a couple of extra test cases I used to check whether exception handling was still working before and after the dlopen call. With the current state of HEAD, the first one works (by which I mean "prints 'sig 11' forever" and the second one fails (by which I means reaches some sort of exit without hitting the signal handler at all). With the attached diff, they both work (as does the original unmodified testcase). This is just a brain dump because I'm off to bed now, hence no change log, and there's still commented-out stuff and inadequate commenting, but I figured I may as well let everyone know what I found out. 'night all! cheers, DaveK
Index: winsup/cygwin/dll_init.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/dll_init.cc,v retrieving revision 1.70 diff -p -u -r1.70 dll_init.cc --- winsup/cygwin/dll_init.cc 5 Feb 2010 15:05:22 -0000 1.70 +++ winsup/cygwin/dll_init.cc 24 Feb 2010 05:05:45 -0000 @@ -329,7 +329,14 @@ dll_dllcrt0_1 (VOID *x) 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); + /* _my_tls.init_exception_handler (_cygtls::handle_exceptions); */ + /* Correction: install a temporary registration with our handler + at the head of the list, and unlink it before returning. */ + extern exception_list *_except_list asm ("%fs:0"); + exception_list seh; + seh.handler = _cygtls::handle_exceptions; + seh.prev = _except_list; + _except_list = &seh; if (p == NULL) p = &__cygwin_user_data; @@ -390,6 +397,8 @@ dll_dllcrt0_1 (VOID *x) res = -1; else res = (DWORD) d; + + _except_list = seh.prev; } /* OBSOLETE: This function is obsolete and will go away in the
#include <dlfcn.h> #include <signal.h> #include <stdio.h> void my_handler (int sig) { printf ("sig %d\n", sig); } int main( int argc, char** argv ) { signal (SIGSEGV, my_handler); *(volatile unsigned int *)0; void* dll = dlopen( "mutex.dll", RTLD_NOW ); dlclose( dll ); }
#include <dlfcn.h> #include <signal.h> #include <stdio.h> void my_handler (int sig) { printf ("sig %d\n", sig); } int main( int argc, char** argv ) { signal (SIGSEGV, my_handler); void* dll = dlopen( "mutex.dll", RTLD_NOW ); *(volatile unsigned int *)0; dlclose( dll ); }
-- 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