diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 31876aec9..f584553dd 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,23 @@ +2004-03-06 Christopher Faylor <cgf@redhat.com> + + * fork.cc (fork_parent): Save parent pid in a temporary variable since + child could conceivably exit before function returns, rendering the + child's shared memory area invalid. + + * cygtls.h (_cygtls::incyg): Declare new field. + (_cygtls::in_exception): Define new function. + * exceptions.cc (setup_handler): Remove locked flag. Use 'incyg' flag + and in_exception function to determine when we're in a cygwin function. + (_cygtls::call_signal_handler): Decrement incyg flag prior to calling a + handler. Increment it on return. + * gendef (_sigfe): Increment incyg flag. Use testl for zero testing + rather than orl, for consistency. + (_sigbe): Decrement incyg flag. Use testl for zero testing rather than + orl, for consistency. + (_cygtls::pop): Use testl for zero testing rather than orl, for + consistency. + (stabilize_sig_stack): Ditto. + 2004-03-05 Christopher Faylor <cgf@redhat.com> * gendef (sigdelayed): Handle return here rather than going through diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index 444da265c..5e2576635 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -113,6 +113,7 @@ struct _cygtls int sig; unsigned stacklock; unsigned spinning; + unsigned incyg; __stack_t stack[TLS_STACK_SIZE]; unsigned padding[0]; @@ -126,7 +127,8 @@ struct _cygtls void remove (DWORD); void push (__stack_t, bool) __attribute__ ((regparm (3))); __stack_t pop () __attribute__ ((regparm (1))); - bool isinitialized () {return initialized == CYGTLS_INITIALIZED || initialized == CYGTLS_EXCEPTION;} + bool isinitialized () const {return initialized == CYGTLS_INITIALIZED || initialized == CYGTLS_EXCEPTION;} + bool in_exception () const {return initialized == CYGTLS_EXCEPTION;} void set_state (bool); void reset_exception (); bool interrupt_now (CONTEXT *, int, void *, struct sigaction&) diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 45d840aee..086ced32b 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -742,7 +742,6 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls) { CONTEXT cx; bool interrupted = false; - bool locked = false; if (tls->sig) { @@ -754,18 +753,17 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls) for (int i = 0; i < CALL_HANDLER_RETRY; i++) { tls->lock (); - locked = true; - if (tls->stackptr > tls->stack) + if (tls->incyg || tls->in_exception ()) { tls->reset_exception (); tls->interrupt_setup (sig, handler, siga); sigproc_printf ("interrupted known cygwin routine"); interrupted = true; + tls->unlock (); break; } tls->unlock (); - locked = false; DWORD res; HANDLE hth = (HANDLE) *tls; @@ -776,7 +774,7 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls) since we don't want to stall the signal handler. FIXME: Will this result in noticeable delays? If the thread is already suspended (which can occur when a program has called - SuspendThread on itself then just queue the signal. */ + SuspendThread on itself) then just queue the signal. */ #ifndef DEBUGGING sigproc_printf ("suspending mainthread"); @@ -788,7 +786,7 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls) #endif res = SuspendThread (hth); /* Just set pending if thread is already suspended */ - if (res || tls->stackptr > tls->stack) + if (res || tls->incyg) { (void) ResumeThread (hth); break; @@ -811,8 +809,6 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls) } out: - if (locked) - tls->unlock (); if (interrupted && tls->event) { HANDLE h = tls->event; @@ -1185,8 +1181,10 @@ _cygtls::call_signal_handler () sigset_t this_oldmask = oldmask; int this_errno = saved_errno; set_process_mask (newmask); + incyg--; sig = 0; sigfunc (thissig); + incyg++; set_process_mask (this_oldmask); if (this_errno >= 0) set_errno (this_errno); diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index c26d2d678..0103b0dd3 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -512,6 +512,10 @@ fork_parent (HANDLE& hParent, dll *&first_dll, goto cleanup; } + int forked_pid; + + forked_pid = forked->pid; + /* Initialize things that are done later in dll_crt0_1 that aren't done for the forkee. */ strcpy (forked->progname, myself->progname); @@ -621,7 +625,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll, pi.hThread = NULL; pthread::atforkparent (); - return forked->pid; + return forked_pid; /* Common cleanup code for failure cases */ cleanup: diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef index a208cbe31..c126fc03f 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -95,12 +95,13 @@ __sigfe: movl \$1,%eax # potential lock value lock xchgl %eax,$tls::stacklock(%edx) # see if we can grab it movl %eax,$tls::spinning(%edx) # flag if we are waiting for lock - orl %eax,%eax # it will be zero + testl %eax,%eax # it will be zero jz 2f # if so xorl %eax,%eax # nope. It was not zero call _low_priority_sleep # should be a short-time thing, so jmp 1b # sleep and loop -2: movl \$4,%eax # have the lock, now increment the +2: incl $tls::incyg(%edx) + movl \$4,%eax # have the lock, now increment the xadd %eax,$tls::stackptr(%edx) # stack pointer and get pointer leal __sigbe,%ebx # new place to return to xchgl %ebx,12(%esp) # exchange with real return value @@ -120,7 +121,7 @@ __sigbe: movl \$1,%eax # potential lock value lock xchgl %eax,$tls::stacklock(%edx) # see if we can grab it movl %eax,$tls::spinning(%edx) # flag if we are waiting for lock - orl %eax,%eax # it will be zero + testl %eax,%eax # it will be zero jz 2f # if so xorl %eax,%eax # nope. not zero call _low_priority_sleep # sleep @@ -130,6 +131,7 @@ __sigbe: xorl %ebx,%ebx xchgl %ebx,-4(%eax) # get return address from signal stack xchgl %ebx,8(%esp) # restore ebx/real return address + decl $tls::incyg(%edx) decl $tls::stacklock(%edx) # release lock popl %eax popl %edx @@ -145,7 +147,7 @@ _sigreturn: movl \$1,%eax # potential lock value lock xchgl %eax,$tls::stacklock(%edx) # see if we can grab it movl %eax,$tls::spinning(%edx) # flag if we are waiting for lock - orl %eax,%eax # it will be zero + testl %eax,%eax # it will be zero jz 2f # if so xorl %eax,%eax # nope. not zero call _low_priority_sleep # sleep @@ -220,7 +222,7 @@ __ZN7_cygtls4lockEv: movl %eax,%edi 1: movl \$1,%eax lock xchgl %eax,$tls::pstacklock(%edi) - orl %eax,%eax + testl %eax,%eax jz 2f xorl %eax,%eax call _low_priority_sleep @@ -244,7 +246,7 @@ stabilize_sig_stack: movl \$1,%eax lock xchgl %eax,$tls::stacklock(%edx) movl %eax,$tls::spinning(%edx) # flag if we are waiting for lock - orl %eax,%eax + testl %eax,%eax jz 2f xorl %eax,%eax call _low_priority_sleep diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h index 2ff27339b..96b06d7f2 100644 --- a/winsup/cygwin/tlsoffsets.h +++ b/winsup/cygwin/tlsoffsets.h @@ -1,101 +1,105 @@ //;# autogenerated: Do not edit. -//; $tls::sizeof__cygtls = 3744; -//; $tls::func = -3744; +//; $tls::sizeof__cygtls = 3748; +//; $tls::func = -3748; //; $tls::pfunc = 0; -//; $tls::saved_errno = -3740; +//; $tls::saved_errno = -3744; //; $tls::psaved_errno = 4; -//; $tls::sa_flags = -3736; +//; $tls::sa_flags = -3740; //; $tls::psa_flags = 8; -//; $tls::oldmask = -3732; +//; $tls::oldmask = -3736; //; $tls::poldmask = 12; -//; $tls::newmask = -3728; +//; $tls::newmask = -3732; //; $tls::pnewmask = 16; -//; $tls::event = -3724; +//; $tls::event = -3728; //; $tls::pevent = 20; -//; $tls::errno_addr = -3720; +//; $tls::errno_addr = -3724; //; $tls::perrno_addr = 24; -//; $tls::initialized = -3716; +//; $tls::initialized = -3720; //; $tls::pinitialized = 28; -//; $tls::sigmask = -3712; +//; $tls::sigmask = -3716; //; $tls::psigmask = 32; -//; $tls::sigwait_mask = -3708; +//; $tls::sigwait_mask = -3712; //; $tls::psigwait_mask = 36; -//; $tls::sigwait_info = -3704; +//; $tls::sigwait_info = -3708; //; $tls::psigwait_info = 40; -//; $tls::threadkill = -3700; +//; $tls::threadkill = -3704; //; $tls::pthreadkill = 44; -//; $tls::infodata = -3696; +//; $tls::infodata = -3700; //; $tls::pinfodata = 48; -//; $tls::tid = -3548; +//; $tls::tid = -3552; //; $tls::ptid = 196; -//; $tls::local_clib = -3544; +//; $tls::local_clib = -3548; //; $tls::plocal_clib = 200; -//; $tls::locals = -2616; +//; $tls::locals = -2620; //; $tls::plocals = 1128; -//; $tls::prev = -1048; +//; $tls::prev = -1052; //; $tls::pprev = 2696; -//; $tls::next = -1044; +//; $tls::next = -1048; //; $tls::pnext = 2700; -//; $tls::stackptr = -1040; +//; $tls::stackptr = -1044; //; $tls::pstackptr = 2704; -//; $tls::sig = -1036; +//; $tls::sig = -1040; //; $tls::psig = 2708; -//; $tls::stacklock = -1032; +//; $tls::stacklock = -1036; //; $tls::pstacklock = 2712; -//; $tls::spinning = -1028; +//; $tls::spinning = -1032; //; $tls::pspinning = 2716; +//; $tls::incyg = -1028; +//; $tls::pincyg = 2720; //; $tls::stack = -1024; -//; $tls::pstack = 2720; +//; $tls::pstack = 2724; //; $tls::padding = 0; -//; $tls::ppadding = 3744; +//; $tls::ppadding = 3748; //; __DATA__ -#define tls_func (-3744) +#define tls_func (-3748) #define tls_pfunc (0) -#define tls_saved_errno (-3740) +#define tls_saved_errno (-3744) #define tls_psaved_errno (4) -#define tls_sa_flags (-3736) +#define tls_sa_flags (-3740) #define tls_psa_flags (8) -#define tls_oldmask (-3732) +#define tls_oldmask (-3736) #define tls_poldmask (12) -#define tls_newmask (-3728) +#define tls_newmask (-3732) #define tls_pnewmask (16) -#define tls_event (-3724) +#define tls_event (-3728) #define tls_pevent (20) -#define tls_errno_addr (-3720) +#define tls_errno_addr (-3724) #define tls_perrno_addr (24) -#define tls_initialized (-3716) +#define tls_initialized (-3720) #define tls_pinitialized (28) -#define tls_sigmask (-3712) +#define tls_sigmask (-3716) #define tls_psigmask (32) -#define tls_sigwait_mask (-3708) +#define tls_sigwait_mask (-3712) #define tls_psigwait_mask (36) -#define tls_sigwait_info (-3704) +#define tls_sigwait_info (-3708) #define tls_psigwait_info (40) -#define tls_threadkill (-3700) +#define tls_threadkill (-3704) #define tls_pthreadkill (44) -#define tls_infodata (-3696) +#define tls_infodata (-3700) #define tls_pinfodata (48) -#define tls_tid (-3548) +#define tls_tid (-3552) #define tls_ptid (196) -#define tls_local_clib (-3544) +#define tls_local_clib (-3548) #define tls_plocal_clib (200) -#define tls_locals (-2616) +#define tls_locals (-2620) #define tls_plocals (1128) -#define tls_prev (-1048) +#define tls_prev (-1052) #define tls_pprev (2696) -#define tls_next (-1044) +#define tls_next (-1048) #define tls_pnext (2700) -#define tls_stackptr (-1040) +#define tls_stackptr (-1044) #define tls_pstackptr (2704) -#define tls_sig (-1036) +#define tls_sig (-1040) #define tls_psig (2708) -#define tls_stacklock (-1032) +#define tls_stacklock (-1036) #define tls_pstacklock (2712) -#define tls_spinning (-1028) +#define tls_spinning (-1032) #define tls_pspinning (2716) +#define tls_incyg (-1028) +#define tls_pincyg (2720) #define tls_stack (-1024) -#define tls_pstack (2720) +#define tls_pstack (2724) #define tls_padding (0) -#define tls_ppadding (3744) +#define tls_ppadding (3748)