From fd4a56afe8f8cd8664d655c5cf04ef33d1695c78 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Wed, 24 Feb 2010 00:03:42 +0000 Subject: [PATCH] * cygtls.cc (_cygtls::init_exception_handler): Force installation of our exception handler to always be at the beginning. --- winsup/cygwin/ChangeLog | 5 +++++ winsup/cygwin/cygtls.cc | 31 ++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 963b3998b..4d59cfbe5 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,8 @@ +2010-02-23 Christopher Faylor + + * cygtls.cc (_cygtls::init_exception_handler): Force installation of + our exception handler to always be at the beginning. + 2010-02-23 Christopher Faylor * thread.cc (pthread_mutex::unlock): Don't attempt to unlock if there diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc index b90b25fa2..32227e287 100644 --- a/winsup/cygwin/cygtls.cc +++ b/winsup/cygwin/cygtls.cc @@ -240,14 +240,30 @@ _cygtls::init_exception_handler (exception_handler *eh) a problem if some previous exception handler tries to do things that are better left to Cygwin. I await the cygwin mailing list notification of this event with bated breath. + (cgf 2009-07-17) - (cgf 2009-07-17) */ - for (exception_list *e = _except_list; - e != NULL && e != (exception_list *) -1; - e = e->prev) - if (e == &el) - return; - el.handler = eh; + A change in plans: In the not-so-distant past of 2010-02-23 it was + discovered that something was moving in ahead of cygwin's exception + handler so just detecting that the exception handler was loaded wasn't + good enough. I sort of anticipated this. So, the next step is to remove + the old exception handler from the list and add it to the beginning. + + The next step will probably be to call this function at various points + in cygwin (like from _cygtls::setup_fault maybe) to absoltely ensure that + we have control. For now, however, this seems good enough. + (cgf 2010-02-23) + */ + exception_list *e = _except_list; + if (e == &el) + return; + while (e && e != (exception_list *) -1) + if (e->prev != &el) + e = e->prev; + else + { + e->prev = el.prev; + break; + } /* Apparently Windows stores some information about an exception and tries to figure out if the SEH which returned 0 last time actually solved the problem, or if the problem still persists (e.g. same exception at same @@ -259,6 +275,7 @@ _cygtls::init_exception_handler (exception_handler *eh) Windows 2008, which irremediably gets into an endless loop, taking 100% CPU. That's why we reverted to a normal SEH chain and changed the way the exception handler returns to the application. */ + el.handler = eh; el.prev = _except_list; _except_list = ⪙ }