* cygtls.cc (_cygtls::fixup_after_fork): Remove unneeded setting of oldmask.
* exceptions.cc: Remove some __I386__ conditionals. (handle_exceptions): Move ppid test to outside of a loop for efficiency. (setup_handler): Make debugging output more wordy. (_cygtls::call_signal_handler): To avoid a race, use lock/unlock to synchronize with signal thread and ensure that signal_arrived event has actually been set. * gendef (_sigfe): Use ebx for all sigstack manipulations to ensure that the register is saved. Move setting of incyg to within stack lock to avoid setup_handler confusion. (_sigbe): Use ebx for all sigstack manipulations to ensure that the register is saved. (_cygtls::pop): Ditto. (_cygtls::lock): Ditto. (stabilize_sig_stack): Ditto. (setjmp): Ditto. (longjmp): Ditto.
This commit is contained in:
parent
2c4ef10a55
commit
7ea8e226ee
|
@ -1,3 +1,25 @@
|
|||
2004-03-11 Christopher Faylor <cgf@redhat.com>
|
||||
|
||||
* cygtls.cc (_cygtls::fixup_after_fork): Remove unneeded setting of
|
||||
oldmask.
|
||||
* exceptions.cc: Remove some __I386__ conditionals.
|
||||
(handle_exceptions): Move ppid test to outside of a loop for
|
||||
efficiency.
|
||||
(setup_handler): Make debugging output more wordy.
|
||||
(_cygtls::call_signal_handler): To avoid a race, use lock/unlock to
|
||||
synchronize with signal thread and ensure that signal_arrived event has
|
||||
actually been set.
|
||||
* gendef (_sigfe): Use ebx for all sigstack manipulations to ensure
|
||||
that the register is saved. Move setting of incyg to within stack lock
|
||||
to avoid setup_handler confusion.
|
||||
(_sigbe): Use ebx for all sigstack manipulations to ensure that the
|
||||
register is saved.
|
||||
(_cygtls::pop): Ditto.
|
||||
(_cygtls::lock): Ditto.
|
||||
(stabilize_sig_stack): Ditto.
|
||||
(setjmp): Ditto.
|
||||
(longjmp): Ditto.
|
||||
|
||||
2004-03-08 Jaakko Hyvatti <jaakko.hyvatti@iki.fi>
|
||||
|
||||
* fhandler_serial.cc (fhandler_serial::ioctl): Implement TIOCSBRK and
|
||||
|
|
|
@ -138,12 +138,7 @@ _cygtls::init_thread (void *x, DWORD (*func) (void *, void *))
|
|||
void
|
||||
_cygtls::fixup_after_fork ()
|
||||
{
|
||||
if (sig)
|
||||
{
|
||||
set_signal_mask (oldmask);
|
||||
sig = 0;
|
||||
}
|
||||
stacklock = 0;
|
||||
sig = stacklock = 0;
|
||||
stackptr = stack + 1; // FIXME?
|
||||
#ifdef DEBUGGING
|
||||
memset (stackptr, 0, sizeof (stack) - sizeof (stack[0]));
|
||||
|
|
|
@ -187,30 +187,18 @@ exception (EXCEPTION_RECORD *e, CONTEXT *in)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef __i386__
|
||||
#define HAVE_STATUS
|
||||
if (exception_name)
|
||||
small_printf ("Exception: %s at eip=%08x\r\n", exception_name, in->Eip);
|
||||
else
|
||||
small_printf ("Exception %d at eip=%08x\r\n", e->ExceptionCode, in->Eip);
|
||||
small_printf ("eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\r\n",
|
||||
in->Eax, in->Ebx, in->Ecx, in->Edx, in->Esi, in->Edi);
|
||||
small_printf ("ebp=%08x esp=%08x program=%s\r\n",
|
||||
in->Ebp, in->Esp, myself->progname);
|
||||
in->Eax, in->Ebx, in->Ecx, in->Edx, in->Esi, in->Edi);
|
||||
small_printf ("ebp=%08x esp=%08x program=%s, pid %u, thread %s\r\n",
|
||||
in->Ebp, in->Esp, myself->progname, myself->pid, cygthread::name ());
|
||||
small_printf ("cs=%04x ds=%04x es=%04x fs=%04x gs=%04x ss=%04x\r\n",
|
||||
in->SegCs, in->SegDs, in->SegEs, in->SegFs, in->SegGs, in->SegSs);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STATUS
|
||||
system_printf ("Had an exception");
|
||||
#endif
|
||||
in->SegCs, in->SegDs, in->SegEs, in->SegFs, in->SegGs, in->SegSs);
|
||||
}
|
||||
|
||||
#ifdef __i386__
|
||||
/* Print a stack backtrace. */
|
||||
|
||||
#define HAVE_STACK_TRACE
|
||||
|
||||
/* A class for manipulating the stack. */
|
||||
class stack_info
|
||||
{
|
||||
|
@ -300,7 +288,7 @@ stackdump (DWORD ebp, int open_file, bool isexception)
|
|||
small_printf ("%s%08x", j == 0 ? " (" : ", ", thestack.sf.Params[j]);
|
||||
small_printf (")\r\n");
|
||||
}
|
||||
small_printf ("End of stack trace%s",
|
||||
small_printf ("End of stack trace%s\n",
|
||||
i == 16 ? " (more stack frames may be present)" : "");
|
||||
}
|
||||
|
||||
|
@ -526,13 +514,13 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
|
|||
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR)
|
||||
{
|
||||
/* Print the exception to the console */
|
||||
for (int i = 0; status_info[i].name; i++)
|
||||
if (status_info[i].code == e.ExceptionCode)
|
||||
{
|
||||
if (!myself->ppid_handle)
|
||||
if (!myself->ppid_handle)
|
||||
for (int i = 0; status_info[i].name; i++)
|
||||
if (status_info[i].code == e.ExceptionCode)
|
||||
{
|
||||
system_printf ("Exception: %s", status_info[i].name);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Another exception could happen while tracing or while exiting.
|
||||
Only do this once. */
|
||||
|
@ -565,23 +553,11 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
|
|||
sig_send (NULL, si, &_my_tls); // Signal myself
|
||||
return 1;
|
||||
}
|
||||
#endif /* __i386__ */
|
||||
|
||||
#ifndef HAVE_STACK_TRACE
|
||||
void
|
||||
stack (void)
|
||||
{
|
||||
system_printf ("Stack trace not yet supported on this machine.");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Utilities to call a user supplied exception handler. */
|
||||
|
||||
#define SIG_NONMASKABLE (SIGTOMASK (SIGKILL) | SIGTOMASK (SIGSTOP))
|
||||
|
||||
#ifdef __i386__
|
||||
#define HAVE_CALL_HANDLER
|
||||
|
||||
/* Non-raceable sigsuspend
|
||||
* Note: This implementation is based on the Single UNIX Specification
|
||||
* man page. This indicates that sigsuspend always returns -1 and that
|
||||
|
@ -692,8 +668,7 @@ interruptible (DWORD pc)
|
|||
return res;
|
||||
}
|
||||
void __stdcall
|
||||
_cygtls::interrupt_setup (int sig, void *handler,
|
||||
struct sigaction& siga)
|
||||
_cygtls::interrupt_setup (int sig, void *handler, struct sigaction& siga)
|
||||
{
|
||||
push ((__stack_t) sigdelayed, false);
|
||||
oldmask = myself->getsigmask ();
|
||||
|
@ -718,7 +693,7 @@ _cygtls::interrupt_setup (int sig, void *handler,
|
|||
|
||||
bool
|
||||
_cygtls::interrupt_now (CONTEXT *ctx, int sig, void *handler,
|
||||
struct sigaction& siga)
|
||||
struct sigaction& siga)
|
||||
{
|
||||
push ((__stack_t) ctx->Eip, false);
|
||||
interrupt_setup (sig, handler, siga);
|
||||
|
@ -755,9 +730,10 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls)
|
|||
tls->lock ();
|
||||
if (tls->incyg || tls->in_exception ())
|
||||
{
|
||||
sigproc_printf ("controlled interrupt. incyg %d, exception %d, stackptr %p, stack %p, stackptr[-1] %p",
|
||||
tls->incyg, tls->in_exception (), tls->stackptr, tls->stack, tls->stackptr[-1]);
|
||||
tls->reset_exception ();
|
||||
tls->interrupt_setup (sig, handler, siga);
|
||||
sigproc_printf ("interrupted known cygwin routine");
|
||||
interrupted = true;
|
||||
tls->unlock ();
|
||||
break;
|
||||
|
@ -791,7 +767,10 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls)
|
|||
(void) ResumeThread (hth);
|
||||
break;
|
||||
}
|
||||
if (!tls->incyg && !tls->in_exception () && !tls->spinning && !tls->locked ())
|
||||
if (tls->incyg || tls->in_exception () || tls->spinning || tls->locked ())
|
||||
sigproc_printf ("incyg %d, in_exception %d, spinning %d, locked %d\n",
|
||||
tls->incyg, tls->in_exception (), tls->spinning, tls->locked ());
|
||||
else
|
||||
{
|
||||
cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
|
||||
if (!GetThreadContext (hth, &cx))
|
||||
|
@ -818,11 +797,6 @@ out:
|
|||
sigproc_printf ("signal %d %sdelivered", sig, interrupted ? "" : "not ");
|
||||
return interrupted;
|
||||
}
|
||||
#endif /* i386 */
|
||||
|
||||
#ifndef HAVE_CALL_HANDLER
|
||||
#error "Need to supply machine dependent setup_handler"
|
||||
#endif
|
||||
|
||||
/* Keyboard interrupt handler. */
|
||||
static BOOL WINAPI
|
||||
|
@ -1168,10 +1142,10 @@ int
|
|||
_cygtls::call_signal_handler ()
|
||||
{
|
||||
int this_sa_flags = 0;
|
||||
/* Call signal handler. No need to set stacklock since sig effectively
|
||||
implies that. */
|
||||
/* Call signal handler. */
|
||||
while (sig)
|
||||
{
|
||||
lock (); unlock (); // make sure synchronized
|
||||
this_sa_flags = sa_flags;
|
||||
int thissig = sig;
|
||||
void (*sigfunc) (int) = func;
|
||||
|
@ -1196,7 +1170,9 @@ _cygtls::call_signal_handler ()
|
|||
extern "C" void __stdcall
|
||||
reset_signal_arrived ()
|
||||
{
|
||||
// NEEDED? WaitForSingleObject (signal_arrived, 10);
|
||||
(void) ResetEvent (signal_arrived);
|
||||
sigproc_printf ("reset signal_arrived");
|
||||
if (_my_tls.stackptr > _my_tls.stack) debug_printf ("stackptr[-1] %p", _my_tls.stackptr[-1]);
|
||||
if (_my_tls.stackptr > _my_tls.stack)
|
||||
debug_printf ("stackptr[-1] %p", _my_tls.stackptr[-1]);
|
||||
}
|
||||
|
|
|
@ -91,50 +91,50 @@ EOF
|
|||
__sigfe:
|
||||
pushl %ebx
|
||||
pushl %edx
|
||||
1: movl %fs:4,%edx # location of bottom of stack
|
||||
incl $tls::incyg(%edx)
|
||||
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
|
||||
movl %fs:4,%ebx # location of bottom of stack
|
||||
1: movl \$1,%eax # potential lock value
|
||||
lock xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it
|
||||
movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
|
||||
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
|
||||
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
|
||||
movl %ebx,(%eax) # store real return value on alt stack
|
||||
decl $tls::stacklock(%edx) # remove lock
|
||||
xadd %eax,$tls::stackptr(%ebx) # stack pointer and get pointer
|
||||
leal __sigbe,%edx # new place to return to
|
||||
xchgl %edx,12(%esp) # exchange with real return value
|
||||
movl %edx,(%eax) # store real return value on alt stack
|
||||
incl $tls::incyg(%ebx)
|
||||
decl $tls::stacklock(%ebx) # remove lock
|
||||
popl %edx # restore saved value
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
.global __sigbe
|
||||
.stabs "_sigbe:F(0,1)",36,0,0,__sigbe
|
||||
__sigbe:
|
||||
__sigbe: # return here after cygwin syscall
|
||||
pushl %edx
|
||||
pushl %ebx
|
||||
pushl %edx # return here after cygwin syscall
|
||||
pushl %eax # don't clobber
|
||||
1: movl %fs:4,%edx # address of bottom of tls
|
||||
1: movl %fs:4,%ebx # address of bottom of tls
|
||||
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
|
||||
lock xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it
|
||||
movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
|
||||
testl %eax,%eax # it will be zero
|
||||
jz 2f # if so
|
||||
xorl %eax,%eax # nope. not zero
|
||||
call _low_priority_sleep # sleep
|
||||
jmp 1b # and loop
|
||||
2: movl \$-4,%eax # now decrement aux stack
|
||||
xadd %eax,$tls::stackptr(%edx) # and get pointer
|
||||
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
|
||||
xadd %eax,$tls::stackptr(%ebx) # and get pointer
|
||||
xorl %edx,%edx
|
||||
xchgl %edx,-4(%eax) # get return address from signal stack
|
||||
xchgl %edx,8(%esp) # restore ebx/real return address
|
||||
decl $tls::incyg(%ebx)
|
||||
decl $tls::stacklock(%ebx) # release lock
|
||||
popl %eax
|
||||
popl %edx
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
.global _sigreturn
|
||||
|
@ -190,7 +190,7 @@ _sigdelayed:
|
|||
movl %fs:4,%ebx
|
||||
incl $tls::incyg(%ebx)
|
||||
pushl $tls::saved_errno(%ebx) # saved errno
|
||||
3: pushl $tls::oldmask(%ebx) # oldmask
|
||||
pushl $tls::oldmask(%ebx) # oldmask
|
||||
pushl $tls::sig(%ebx) # signal argument
|
||||
pushl \$_sigreturn
|
||||
|
||||
|
@ -211,27 +211,27 @@ _sigdelayed:
|
|||
__ZN7_cygtls3popEv:
|
||||
1: pushl %ebx
|
||||
pushl %edx # FIXME: needed?
|
||||
movl %eax,%edx
|
||||
movl \$-4,%ebx
|
||||
xadd %ebx,$tls::pstackptr(%edx)
|
||||
movl %eax,%ebx
|
||||
movl \$-4,%edx
|
||||
xadd %edx,$tls::pstackptr(%ebx)
|
||||
xorl %eax,%eax
|
||||
xchgl %eax,-4(%ebx)
|
||||
xchgl %eax,-4(%edx)
|
||||
popl %edx # FIXME: needed?
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
.global __ZN7_cygtls4lockEv
|
||||
__ZN7_cygtls4lockEv:
|
||||
pushl %edi
|
||||
movl %eax,%edi
|
||||
pushl %ebx
|
||||
movl %eax,%ebx
|
||||
1: movl \$1,%eax
|
||||
lock xchgl %eax,$tls::pstacklock(%edi)
|
||||
lock xchgl %eax,$tls::pstacklock(%ebx)
|
||||
testl %eax,%eax
|
||||
jz 2f
|
||||
xorl %eax,%eax
|
||||
call _low_priority_sleep
|
||||
jmp 1b
|
||||
2: popl %edi
|
||||
2: popl %ebx
|
||||
ret
|
||||
|
||||
.global __ZN7_cygtls6unlockEv
|
||||
|
@ -246,24 +246,24 @@ __ZN7_cygtls6lockedEv:
|
|||
|
||||
.extern __ZN7_cygtls19call_signal_handlerEv
|
||||
stabilize_sig_stack:
|
||||
1: movl %fs:4,%edx
|
||||
incl $tls::incyg(%edx)
|
||||
movl \$1,%eax
|
||||
lock xchgl %eax,$tls::stacklock(%edx)
|
||||
movl %eax,$tls::spinning(%edx) # flag if we are waiting for lock
|
||||
movl %fs:4,%ebx
|
||||
incl $tls::incyg(%ebx)
|
||||
1: movl \$1,%eax
|
||||
lock xchgl %eax,$tls::stacklock(%ebx)
|
||||
movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
|
||||
testl %eax,%eax
|
||||
jz 2f
|
||||
xorl %eax,%eax
|
||||
call _low_priority_sleep
|
||||
jmp 1b
|
||||
2: cmpl \$0,$tls::sig(%edx)
|
||||
2: cmpl \$0,$tls::sig(%ebx)
|
||||
jz 3f
|
||||
decl $tls::stacklock(%edx) # unlock
|
||||
decl $tls::stacklock(%ebx) # unlock
|
||||
movl \$-$tls::sizeof__cygtls,%eax # point to beginning
|
||||
addl %edx,%eax # of tls block
|
||||
addl %ebx,%eax # of tls block
|
||||
call __ZN7_cygtls19call_signal_handlerEv
|
||||
jmp 1b
|
||||
3: decl $tls::incyg(%edx)
|
||||
3: decl $tls::incyg(%ebx)
|
||||
ret
|
||||
EOF
|
||||
}
|
||||
|
@ -301,11 +301,11 @@ _setjmp:
|
|||
movw %ax,40(%edi)
|
||||
movw %ss,%ax
|
||||
movw %ax,42(%edi)
|
||||
pushl %edx
|
||||
pushl %ebx
|
||||
call stabilize_sig_stack
|
||||
movl $tls::stackptr(%edx),%eax # save stack pointer contents
|
||||
decl $tls::stacklock(%edx)
|
||||
popl %edx
|
||||
movl $tls::stackptr(%ebx),%eax # save stack pointer contents
|
||||
decl $tls::stacklock(%ebx)
|
||||
popl %ebx
|
||||
movl %eax,44(%edi)
|
||||
popl %edi
|
||||
movl \$0,%eax
|
||||
|
@ -319,8 +319,8 @@ _longjmp:
|
|||
movl 8(%ebp),%edi # address of buffer
|
||||
call stabilize_sig_stack
|
||||
movl 44(%edi),%eax # get old signal stack
|
||||
movl %eax,$tls::stackptr(%edx) # restore
|
||||
decl $tls::stacklock(%edx) # relinquish lock
|
||||
movl %eax,$tls::stackptr(%ebx) # restore
|
||||
decl $tls::stacklock(%ebx) # relinquish lock
|
||||
|
||||
movl 12(%ebp),%eax
|
||||
testl %eax,%eax
|
||||
|
|
Loading…
Reference in New Issue