* 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.
This commit is contained in:
Christopher Faylor 2008-03-01 13:18:22 +00:00
parent 76ff710cfa
commit 813767de3d
4 changed files with 22 additions and 20 deletions

View File

@ -1,3 +1,12 @@
2008-03-01 Corinna Vinschen <corinna@vinschen.de>
* 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 <corinna@vinschen.de> 2008-02-29 Corinna Vinschen <corinna@vinschen.de>
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Call close_fs * fhandler_disk_file.cc (fhandler_disk_file::fchmod): Call close_fs

View File

@ -247,8 +247,7 @@ _cygtls::handle_threadlist_exception (EXCEPTION_RECORD *e, exception_list *frame
extern void *threadlist_exception_return; extern void *threadlist_exception_return;
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); 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

View File

@ -599,8 +599,6 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT
return 1; 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 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); 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; goto out;
} }
rtl_unwind (frame, e);
open_stackdumpfile (); open_stackdumpfile ();
exception (e, in); exception (e, in);
stackdump ((DWORD) ebp, 0, 1); 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 sig_send (NULL, si, &me); // Signal myself
me.incyg--; me.incyg--;
e->ExceptionFlags = 0; 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: out:
SetThreadContext (GetCurrentThread (), in); return 0;
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. */

View File

@ -332,12 +332,14 @@ _setjmp:
movw %ax,40(%edi) movw %ax,40(%edi)
movw %ss,%ax movw %ss,%ax
movw %ax,42(%edi) movw %ax,42(%edi)
movl %fs:0,%eax
movl %eax,44(%edi)
pushl %ebx pushl %ebx
call stabilize_sig_stack call stabilize_sig_stack
movl $tls::stackptr(%ebx),%eax # save stack pointer contents movl $tls::stackptr(%ebx),%eax # save stack pointer contents
decl $tls::stacklock(%ebx) decl $tls::stacklock(%ebx)
popl %ebx popl %ebx
movl %eax,44(%edi) movl %eax,48(%edi)
popl %edi popl %edi
movl \$0,%eax movl \$0,%eax
leave leave
@ -371,6 +373,8 @@ ___sjfault:
movw %ax,40(%edi) movw %ax,40(%edi)
movw %ss,%ax movw %ss,%ax
movw %ax,42(%edi) movw %ax,42(%edi)
movl %fs:0,%eax
movl %eax,44(%edi)
popl %edi popl %edi
movl \$0,%eax movl \$0,%eax
leave leave
@ -391,6 +395,8 @@ ___ljfault:
movl 24(%edi),%ebp movl 24(%edi),%ebp
pushfl pushfl
popl %ebx popl %ebx
movl 44(%edi),%eax
movl %eax,%fs:0
movw 42(%edi),%ax movw 42(%edi),%ax
movw %ax,%ss movw %ax,%ss
movl 28(%edi),%esp movl 28(%edi),%esp
@ -415,7 +421,7 @@ _longjmp:
movl %esp,%ebp movl %esp,%ebp
movl 8(%ebp),%edi # address of buffer movl 8(%ebp),%edi # address of buffer
call stabilize_sig_stack 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 movl %eax,$tls::stackptr(%ebx) # restore
decl $tls::stacklock(%ebx) # relinquish lock decl $tls::stacklock(%ebx) # relinquish lock
xorl %eax,%eax xorl %eax,%eax
@ -430,6 +436,8 @@ _longjmp:
movl 24(%edi),%ebp movl 24(%edi),%ebp
pushfl pushfl
popl %ebx popl %ebx
movl 44(%edi),%eax
movl %eax,%fs:0
movw 42(%edi),%ax movw 42(%edi),%ax
movw %ax,%ss movw %ax,%ss
movl 28(%edi),%esp movl 28(%edi),%esp