From d239805457f0dc790559b2173e943e5aebe90c4e Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Mon, 30 Jul 2012 03:44:40 +0000 Subject: [PATCH] * cygwait.cc (cancelable_wait): Add some debugging-only output. * exceptions.cc (sig_handle_tty_stop): Make sure that incyg is cleared when exiting if we have no parent process. Only wait for signal_arrived. (sigpacket::process): Make continue_now a bool. Delay sending signal_arrived until the end. Make code more defensive to avoid calling signal handler when stopped. Only set signal_arrived when stopped. * sigproc.cc (sig_hold): Rename from sigCONT. Make static. (sig_send): Accommodate sigCONT -> sig_hold rename. (wait_sig): Ditto. * sigproc.h (sigCONT): Delete declaration. * fhandler_console.cc (fhandler_console::write): Use new '%0c' facility to print characters. Change to paranoid to avoid excessive strace output. * fhandler_tty.cc (fhandler_pty_master::accept_input): Make frequent strace printf "paranoid" to help cut down on strace output size. * signal.cc (sigsuspend): Add standard syscall strace output. (sigpause): Ditto. (pause): Ditto. * cygtls.h (_cygtls::reset_signal_arrived): New function. --- winsup/cygwin/ChangeLog | 26 +++++++++++- winsup/cygwin/cygwait.cc | 3 +- winsup/cygwin/exceptions.cc | 66 +++++++++++++++---------------- winsup/cygwin/fhandler_console.cc | 3 +- winsup/cygwin/fhandler_tty.cc | 2 +- winsup/cygwin/signal.cc | 12 ++++-- winsup/cygwin/sigproc.cc | 9 ++--- winsup/cygwin/sigproc.h | 2 - 8 files changed, 75 insertions(+), 48 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 880dab278..915aa5527 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,6 +1,30 @@ 2012-07-29 Christopher Faylor - * cygtls.cc (_cygtls::reset_signal_arrived): New function. + * cygwait.cc (cancelable_wait): Add some debugging-only output. + * exceptions.cc (sig_handle_tty_stop): Make sure that incyg is cleared + when exiting if we have no parent process. Only wait for signal_arrived. + (sigpacket::process): Make continue_now a bool. Delay sending + signal_arrived until the end. Make code more defensive to avoid + calling signal handler when stopped. Only set signal_arrived when + stopped. + * sigproc.cc (sig_hold): Rename from sigCONT. Make static. + (sig_send): Accommodate sigCONT -> sig_hold rename. + (wait_sig): Ditto. + * sigproc.h (sigCONT): Delete declaration. + + * fhandler_console.cc (fhandler_console::write): Use new '%0c' facility + to print characters. Change to paranoid to avoid excessive strace + output. + * fhandler_tty.cc (fhandler_pty_master::accept_input): Make frequent + strace printf "paranoid" to help cut down on strace output size. + + * signal.cc (sigsuspend): Add standard syscall strace output. + (sigpause): Ditto. + (pause): Ditto. + +2012-07-29 Christopher Faylor + + * cygtls.h (_cygtls::reset_signal_arrived): New function. (set_signal_arrived::~set_signal_arrived): Use reset_signal_arrived to reset state. * exceptions.cc (sig_handle_tty_stop): Use WAIT_SIGNALED rather than diff --git a/winsup/cygwin/cygwait.cc b/winsup/cygwin/cygwait.cc index d1247f4d1..ee7a705ef 100644 --- a/winsup/cygwin/cygwait.cc +++ b/winsup/cygwin/cygwait.cc @@ -39,7 +39,7 @@ cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask) wait_objects[num++] = object; set_signal_arrived thread_waiting (is_cw_sig_handle, wait_objects[num]); -debug_printf ("thread waiting %d, signal_arrived %p", (int) thread_waiting, _my_tls.signal_arrived); + debug_only_printf ("object %p, thread waiting %d, signal_arrived %p", object, (int) thread_waiting, _my_tls.signal_arrived); DWORD sig_n; if (!thread_waiting) sig_n = WAIT_TIMEOUT + 1; @@ -72,6 +72,7 @@ debug_printf ("thread waiting %d, signal_arrived %p", (int) thread_waiting, _my_ while (1) { res = WaitForMultipleObjects (num, wait_objects, FALSE, INFINITE); + debug_only_printf ("res %d", res); if (res == cancel_n) res = WAIT_CANCELED; else if (res == timeout_n) diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 6c4740059..7db2f00ff 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -735,30 +735,29 @@ sig_handle_tty_stop (int sig) /* Silently ignore attempts to suspend if there is no accommodating cygwin parent to deal with this behavior. */ if (!myself->cygstarted) + myself->process_state &= ~PID_STOPPED; + else { - myself->process_state &= ~PID_STOPPED; - return; - } - - myself->stopsig = sig; - myself->alert_parent (sig); - sigproc_printf ("process %d stopped by signal %d", myself->pid, sig); - HANDLE w4[2]; - w4[0] = sigCONT; - switch (cancelable_wait (sigCONT, cw_infinite, cw_sig_eintr)) - { - case WAIT_OBJECT_0: - case WAIT_SIGNALED: - myself->stopsig = SIGCONT; - myself->alert_parent (SIGCONT); - break; - default: - api_fatal ("WaitSingleObject failed, %E"); - break; + myself->stopsig = sig; + myself->alert_parent (sig); + sigproc_printf ("process %d stopped by signal %d", myself->pid, sig); + /* FIXME! This does nothing to suspend anything other than the main + thread. */ + DWORD res = cancelable_wait (NULL, cw_infinite, cw_sig_eintr); + switch (res) + { + case WAIT_SIGNALED: + myself->stopsig = SIGCONT; + myself->alert_parent (SIGCONT); + break; + default: + api_fatal ("WaitSingleObject returned %d", res); + break; + } } _my_tls.incyg = 0; } -} +} /* end extern "C" */ bool _cygtls::interrupt_now (CONTEXT *cx, int sig, void *handler, @@ -1122,14 +1121,14 @@ set_signal_mask (sigset_t& setmask, sigset_t newmask) int __stdcall sigpacket::process () { - DWORD continue_now; + bool continue_now; struct sigaction dummy = global_sigs[SIGSTOP]; if (si.si_signo != SIGCONT) continue_now = false; else { - continue_now = myself->process_state & PID_STOPPED; + continue_now = ISSTATE (myself, PID_STOPPED); myself->stopsig = 0; myself->process_state &= ~PID_STOPPED; /* Clear pending stop signals */ @@ -1206,9 +1205,7 @@ sigpacket::process () if (si.si_signo == SIGCHLD || si.si_signo == SIGIO || si.si_signo == SIGCONT || si.si_signo == SIGWINCH || si.si_signo == SIGURG) { - sigproc_printf ("default signal %d ignored", si.si_signo); - if (continue_now) - SetEvent (tls->signal_arrived); + sigproc_printf ("signal %d default is currently ignore", si.si_signo); goto done; } @@ -1224,21 +1221,24 @@ sigpacket::process () goto dosig; stop: - /* Eat multiple attempts to STOP */ - if (ISSTATE (myself, PID_STOPPED)) - goto done; handler = (void *) sig_handle_tty_stop; thissig = dummy; dosig: - tls->set_siginfo (this); - /* Dispatch to the appropriate function. */ - sigproc_printf ("signal %d, signal handler %p", si.si_signo, handler); - rc = setup_handler (si.si_signo, handler, thissig, tls); + if (ISSTATE (myself, PID_STOPPED) && !continue_now) + rc = -1; /* No signals delivered if stopped */ + else + { + tls->set_siginfo (this); + /* Dispatch to the appropriate function. */ + sigproc_printf ("signal %d, signal handler %p", si.si_signo, handler); + rc = setup_handler (si.si_signo, handler, thissig, tls); + continue_now = false; + } done: if (continue_now) - SetEvent (sigCONT); + SetEvent (tls->signal_arrived); sigproc_printf ("returning %d", rc); return rc; diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 0208a4863..0dcd1262b 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -2012,8 +2012,7 @@ fhandler_console::write (const void *vsrc, size_t len) while (src < end) { - debug_printf ("at %d(%c) state is %d", *src, isprint (*src) ? *src : ' ', - dev_state.state_); + paranoid_printf ("char %0c state is %d", *src, dev_state.state_); switch (dev_state.state_) { case normal: diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index c29d36594..c5b65c5b8 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -176,7 +176,7 @@ fhandler_pty_master::accept_input () DWORD rc; DWORD written = 0; - termios_printf ("about to write %d chars to slave", bytes_left); + paranoid_printf ("about to write %d chars to slave", bytes_left); rc = WriteFile (get_output_handle (), p, bytes_left, &written, NULL); if (!rc) { diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index f2d68c775..b34defb99 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -517,19 +517,25 @@ sigfillset (sigset_t *set) extern "C" int sigsuspend (const sigset_t *set) { - return handle_sigsuspend (*set); + int res = handle_sigsuspend (*set); + syscall_printf ("%R = sigsuspend(%p)", res, set); + return res; } extern "C" int sigpause (int signal_mask) { - return handle_sigsuspend ((sigset_t) signal_mask); + int res = handle_sigsuspend ((sigset_t) signal_mask); + syscall_printf ("%R = sigpause(%p)", res, signal_mask); + return res; } extern "C" int pause (void) { - return handle_sigsuspend (_my_tls.sigmask); + int res = handle_sigsuspend (_my_tls.sigmask); + syscall_printf ("%R = pause()", res); + return res; } extern "C" int diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index dcfbcbc55..d893fc2d8 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -46,8 +46,7 @@ char NO_COPY myself_nowait_dummy[1] = {'0'};// Flag to sig_send that signal goes #define Static static NO_COPY -HANDLE NO_COPY sigCONT; // Used to "STOP" a process - +Static HANDLE sig_hold; // Used to stop signal processing Static bool sigheld; // True if holding signals Static int nprocs; // Number of deceased children @@ -568,7 +567,7 @@ sig_send (_pinfo *p, int sig) return 0; else if (sig == __SIGNOHOLD || sig == __SIGEXIT) { - SetEvent (sigCONT); + SetEvent (sig_hold); sigheld = false; } else if (&_my_tls == _main_tls) @@ -1345,7 +1344,7 @@ static void WINAPI wait_sig (VOID *) { _sig_tls = &_my_tls; - sigCONT = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); + sig_hold = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); sigproc_printf ("entering ReadFile loop, my_readsig %p, my_sendsig %p", my_readsig, my_sendsig); @@ -1355,7 +1354,7 @@ wait_sig (VOID *) for (;;) { if (pack.si.si_signo == __SIGHOLD) - WaitForSingleObject (sigCONT, INFINITE); + WaitForSingleObject (sig_hold, INFINITE); DWORD nb; pack.tls = NULL; if (!ReadFile (my_readsig, &pack, sizeof (pack), &nb, NULL)) diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index 1374e9bea..06ebd68d8 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -58,8 +58,6 @@ struct sigpacket int __stdcall process () __attribute__ ((regparm (1))); }; -extern HANDLE sigCONT; - void __stdcall sig_dispatch_pending (bool fast = false) __attribute__ ((regparm (1))); void set_signal_mask (sigset_t&, sigset_t) __attribute__ ((regparm (2)));