diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2008-03-02 10:40:39 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2008-03-02 10:40:39 +0000 |
commit | b8d8e052ec17a5ce663d31a7fd77934bf894aa3c (patch) | |
tree | b29fbddd81edaad65b9895fa148a49671180e0cb | |
parent | 3b5d09c6a57fa7d4ca175370fb6bac662b9455c1 (diff) | |
download | newlib-b8d8e052ec17a5ce663d31a7fd77934bf894aa3c.zip newlib-b8d8e052ec17a5ce663d31a7fd77934bf894aa3c.tar.gz newlib-b8d8e052ec17a5ce663d31a7fd77934bf894aa3c.tar.bz2 |
2008-03-01 Christopher Faylor <me+cygwin@cgf.cx>
* cygtls.h (_cygtls::handle_threadlist_exception): Eliminate.
(_cygtls::init_threadlist_exceptions): Ditto.
* cygtls.cc (_cygtls::handle_threadlist_exception): Eliminate.
(_cygtls::init_threadlist_exceptions): Ditto.
(_cygtls::find_tls): Use myfault handling to deal with errors caused by
nonexistent threads.
* sigproc.cc (wait_sig): Eliminate call to init_threadlist_exceptions.
2008-03-01 Christopher Faylor <me+cygwin@cgf.cx>
* cygtls.cc (_cygtls::init_exception_handler): Just return.
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.
-rw-r--r-- | winsup/cygwin/ChangeLog | 23 | ||||
-rw-r--r-- | winsup/cygwin/cygtls.cc | 51 | ||||
-rw-r--r-- | winsup/cygwin/cygtls.h | 2 | ||||
-rw-r--r-- | winsup/cygwin/exceptions.cc | 18 | ||||
-rwxr-xr-x | winsup/cygwin/gendef | 12 | ||||
-rw-r--r-- | winsup/cygwin/sigproc.cc | 1 |
6 files changed, 45 insertions, 62 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index ef73223..b02bab1 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,26 @@ +2008-03-01 Christopher Faylor <me+cygwin@cgf.cx> + + * cygtls.h (_cygtls::handle_threadlist_exception): Eliminate. + (_cygtls::init_threadlist_exceptions): Ditto. + * cygtls.cc (_cygtls::handle_threadlist_exception): Eliminate. + (_cygtls::init_threadlist_exceptions): Ditto. + (_cygtls::find_tls): Use myfault handling to deal with errors caused by + nonexistent threads. + * sigproc.cc (wait_sig): Eliminate call to init_threadlist_exceptions. + +2008-03-01 Christopher Faylor <me+cygwin@cgf.cx> + + * cygtls.cc (_cygtls::init_exception_handler): Just return. + +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> * fhandler_disk_file.cc (fhandler_disk_file::fchmod): Call close_fs diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc index c2d7c2e..88fd497 100644 --- a/winsup/cygwin/cygtls.cc +++ b/winsup/cygwin/cygtls.cc @@ -196,23 +196,28 @@ _cygtls::push (__stack_t addr) *stackptr++ = (__stack_t) addr; } -#define BAD_IX ((size_t) -1) -static size_t NO_COPY threadlist_ix = BAD_IX; _cygtls * _cygtls::find_tls (int sig) { + static int NO_COPY threadlist_ix; + debug_printf ("sig %d\n", sig); sentry here (INFINITE); - __asm__ volatile (".equ _threadlist_exception_return,."); + _cygtls *res = NULL; - for (threadlist_ix = 0; threadlist_ix < nthreads; threadlist_ix++) + threadlist_ix = -1; + + myfault efault; + if (efault.faulted ()) + cygheap->threadlist[threadlist_ix]->remove (INFINITE); + + while (++threadlist_ix < (int) nthreads) if (sigismember (&(cygheap->threadlist[threadlist_ix]->sigwait_mask), sig)) { res = cygheap->threadlist[threadlist_ix]; break; } - threadlist_ix = BAD_IX; return res; } @@ -222,36 +227,6 @@ _cygtls::set_siginfo (sigpacket *pack) infodata = pack->si; } -extern "C" DWORD __stdcall RtlUnwind (void *, void *, void *, DWORD) __attribute__ ((noreturn)); -int -_cygtls::handle_threadlist_exception (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *c, void *) -{ - if (e->ExceptionCode != STATUS_ACCESS_VIOLATION) - { - system_printf ("unhandled exception %p at %p", e->ExceptionCode, c->Eip); - return 1; - } - - sentry here; - if (threadlist_ix == BAD_IX) - { - api_fatal ("called with threadlist_ix %d", BAD_IX); - return 1; - } - - if (!here.acquired ()) - { - system_printf ("couldn't aquire muto"); - return 1; - } - - extern void *threadlist_exception_return; - cygheap->threadlist[threadlist_ix]->remove (INFINITE); - threadlist_ix = 0; - RtlUnwind (frame, threadlist_exception_return, e, 0); - /* Never returns */ -} - /* Set up the exception handler for the current thread. The x86 uses segment register fs, offset 0 to point to the current exception handler. */ @@ -275,9 +250,3 @@ _cygtls::init_exception_handler (exception_handler *eh) el.prev = _except_list; _except_list = ⪙ } - -void -_cygtls::init_threadlist_exceptions () -{ - init_exception_handler (handle_threadlist_exception); -} diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index 97800a7..e60eb35 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -195,9 +195,7 @@ struct _cygtls /* exception handling */ static int handle_exceptions (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *); - static int handle_threadlist_exception (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *c, void *); void init_exception_handler (int (*) (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void*)); - void init_threadlist_exceptions (); void signal_exit (int) __attribute__ ((noreturn, regparm(2))); void copy_context (CONTEXT *) __attribute__ ((regparm(2))); void signal_debugger (int) __attribute__ ((regparm(2))); diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 9dfe6f3..ce98d21 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -583,8 +583,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); @@ -634,6 +632,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); @@ -664,21 +663,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 0d7df4b..28d4b31 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 diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 863f9e1..bcf331e 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -1166,7 +1166,6 @@ wait_sig (VOID *) SetEvent (wait_sig_inited); _sig_tls = &_my_tls; - _sig_tls->init_threadlist_exceptions (); sigproc_printf ("entering ReadFile loop, my_readsig %p, my_sendsig %p", my_readsig, my_sendsig); |