From 813767de3db47bae178d815e32770787bbb2cfed Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sat, 1 Mar 2008 13:18:22 +0000 Subject: [PATCH] * exceptions.cc (_cygtls::handle_exceptions): Only call rtl_unwind when exiting. Just return, don't set thread context. * gendef (_setjmp): Store %fs:0 in jmp_buf. (_sjfault): Ditto. (_ljfault): Restore %fs:0 from jmp_buf. (_longjmp): Ditto. --- winsup/cygwin/ChangeLog | 9 +++++++++ winsup/cygwin/cygtls.cc | 3 +-- winsup/cygwin/exceptions.cc | 18 ++---------------- winsup/cygwin/gendef | 12 ++++++++++-- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 1e5896fb5..94a578851 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,12 @@ +2008-03-01 Corinna Vinschen + + * exceptions.cc (_cygtls::handle_exceptions): Only call rtl_unwind when + exiting. Just return, don't set thread context. + * gendef (_setjmp): Store %fs:0 in jmp_buf. + (_sjfault): Ditto. + (_ljfault): Restore %fs:0 from jmp_buf. + (_longjmp): Ditto. + 2008-02-29 Corinna Vinschen * fhandler_disk_file.cc (fhandler_disk_file::fchmod): Call close_fs diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc index 6b7e0cd51..34ba14934 100644 --- a/winsup/cygwin/cygtls.cc +++ b/winsup/cygwin/cygtls.cc @@ -247,8 +247,7 @@ _cygtls::handle_threadlist_exception (EXCEPTION_RECORD *e, exception_list *frame extern void *threadlist_exception_return; cygheap->threadlist[threadlist_ix]->remove (INFINITE); threadlist_ix = 0; - RtlUnwind (frame, threadlist_exception_return, e, 0); - /* Never returns */ + return 0; } /* Set up the exception handler for the current thread. The x86 uses segment diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 3b4184db0..56f191851 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -599,8 +599,6 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT return 1; } - rtl_unwind (frame, e); - debug_printf ("In cygwin_except_handler exc %p at %p sp %p", e->ExceptionCode, in->Eip, in->Esp); debug_printf ("In cygwin_except_handler sig %d at %p", si.si_signo, in->Eip); @@ -650,6 +648,7 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT goto out; } + rtl_unwind (frame, e); open_stackdumpfile (); exception (e, in); stackdump ((DWORD) ebp, 0, 1); @@ -680,21 +679,8 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT sig_send (NULL, si, &me); // Signal myself me.incyg--; e->ExceptionFlags = 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. */ out: - SetThreadContext (GetCurrentThread (), in); - return 0; /* Never actually returns. This is just to keep gcc happy. */ + return 0; } /* Utilities to call a user supplied exception handler. */ diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef index 0d7df4b09..28d4b3125 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -332,12 +332,14 @@ _setjmp: movw %ax,40(%edi) movw %ss,%ax movw %ax,42(%edi) + movl %fs:0,%eax + movl %eax,44(%edi) pushl %ebx call stabilize_sig_stack movl $tls::stackptr(%ebx),%eax # save stack pointer contents decl $tls::stacklock(%ebx) popl %ebx - movl %eax,44(%edi) + movl %eax,48(%edi) popl %edi movl \$0,%eax leave @@ -371,6 +373,8 @@ ___sjfault: movw %ax,40(%edi) movw %ss,%ax movw %ax,42(%edi) + movl %fs:0,%eax + movl %eax,44(%edi) popl %edi movl \$0,%eax leave @@ -391,6 +395,8 @@ ___ljfault: movl 24(%edi),%ebp pushfl popl %ebx + movl 44(%edi),%eax + movl %eax,%fs:0 movw 42(%edi),%ax movw %ax,%ss movl 28(%edi),%esp @@ -415,7 +421,7 @@ _longjmp: movl %esp,%ebp movl 8(%ebp),%edi # address of buffer call stabilize_sig_stack - movl 44(%edi),%eax # get old signal stack + movl 48(%edi),%eax # get old signal stack movl %eax,$tls::stackptr(%ebx) # restore decl $tls::stacklock(%ebx) # relinquish lock xorl %eax,%eax @@ -430,6 +436,8 @@ _longjmp: movl 24(%edi),%ebp pushfl popl %ebx + movl 44(%edi),%eax + movl %eax,%fs:0 movw 42(%edi),%ax movw %ax,%ss movl 28(%edi),%esp -- 2.43.5