diff options
author | Christopher Faylor <me@cgf.cx> | 2008-02-27 20:16:46 +0300 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2008-02-27 20:16:46 +0300 |
commit | 8ba248a94b612aa0c826204904ed5b1480397362 (patch) | |
tree | af9a90a456da6131d2a922f839c01ae53795e146 /winsup/cygwin/exceptions.cc | |
parent | ca504a0dee89cd4ca92db404601f3a5d0fdef497 (diff) |
* cygtls.cc (_cygtls::handle_threadlist_exception): Make it clear that the
function never actually returns.
* exceptions.cc (_cygtls::handle_exceptions): Jump out of function rather than
returning to avoid meddling by previously installed exception handlers.
Diffstat (limited to 'winsup/cygwin/exceptions.cc')
-rw-r--r-- | winsup/cygwin/exceptions.cc | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 3c0080953..34defe51b 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -659,7 +659,21 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT sig_send (NULL, si, &me); // Signal myself me.incyg--; e->ExceptionFlags = 0; - return 0; + /* The OS adds an exception list frame to the stack. It expects to be + able to remove this entry after the exception handler returned. + However, when unwinding to our frame, our frame becomes the uppermost + frame on the stack (%fs:0 points to frame). This way, our frame + is removed from the exception stack and just disappears. So, we can't + just return here or things will be screwed up by the helpful function + in (presumably) ntdll.dll. + + So, instead, we will do the equivalent of a longjmp here and return + to the caller without visiting any of the helpful code installed prior + to this function. This should work ok, since a longjmp() out of here has + to work if linux signal semantics are to be maintained. */ + + SetThreadContext (GetCurrentThread (), in); + return 0; /* Never actually returns. This is just to keep gcc happy. */ } /* Utilities to call a user supplied exception handler. */ |