* 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.
This commit is contained in:
parent
ca504a0dee
commit
8ba248a94b
|
@ -1,3 +1,11 @@
|
||||||
|
2008-02-27 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2008-02-25 Corinna Vinschen <corinna@vinschen.de>
|
2008-02-25 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* dcrt0.cc (initial_env): Only use local buffer "buf" if DEBUGGING is
|
* dcrt0.cc (initial_env): Only use local buffer "buf" if DEBUGGING is
|
||||||
|
|
|
@ -221,7 +221,7 @@ _cygtls::set_siginfo (sigpacket *pack)
|
||||||
infodata = pack->si;
|
infodata = pack->si;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" DWORD __stdcall RtlUnwind (void *, void *, void *, DWORD);
|
extern "C" DWORD __stdcall RtlUnwind (void *, void *, void *, DWORD) __attribute__ ((noreturn));
|
||||||
int
|
int
|
||||||
_cygtls::handle_threadlist_exception (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *c, void *)
|
_cygtls::handle_threadlist_exception (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *c, void *)
|
||||||
{
|
{
|
||||||
|
@ -248,7 +248,7 @@ _cygtls::handle_threadlist_exception (EXCEPTION_RECORD *e, exception_list *frame
|
||||||
cygheap->threadlist[threadlist_ix]->remove (INFINITE);
|
cygheap->threadlist[threadlist_ix]->remove (INFINITE);
|
||||||
threadlist_ix = 0;
|
threadlist_ix = 0;
|
||||||
RtlUnwind (frame, threadlist_exception_return, e, 0);
|
RtlUnwind (frame, threadlist_exception_return, e, 0);
|
||||||
return 0;
|
/* Never returns */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up the exception handler for the current thread. The x86 uses segment
|
/* Set up the exception handler for the current thread. The x86 uses segment
|
||||||
|
|
|
@ -659,7 +659,21 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT
|
||||||
sig_send (NULL, si, &me); // Signal myself
|
sig_send (NULL, si, &me); // Signal myself
|
||||||
me.incyg--;
|
me.incyg--;
|
||||||
e->ExceptionFlags = 0;
|
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. */
|
/* Utilities to call a user supplied exception handler. */
|
||||||
|
|
Loading…
Reference in New Issue