From 4ab568c60c33a8e0a74a9aa58bcaf15811ba860b Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sat, 26 Nov 2011 19:14:22 +0000 Subject: [PATCH] * exceptions.cc (stackdump): Make global. (signal_exit): Move to sigproc.cc. * sigproc.cc (signal_exit): Move here. Declare stackdump extern. Set my_sendsig to indicate that signals are no longer available. (my_readsig): Make Static again. (sig_send): Interpret ERROR_BROKEN_PIPE as ESRCH. Remove special-case EACCESS errno setting, just setting errno generally, even for "its_me" case. --- winsup/cygwin/ChangeLog | 14 +++++++++- winsup/cygwin/exceptions.cc | 44 +------------------------------ winsup/cygwin/sigproc.cc | 52 ++++++++++++++++++++++++++++++++++--- 3 files changed, 63 insertions(+), 47 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index a3f1e94d2..32482a3cb 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,6 +1,18 @@ +2011-11-26 Christopher Faylor + + * exceptions.cc (stackdump): Make global. + (signal_exit): Move to sigproc.cc. + * sigproc.cc (signal_exit): Move here. Declare stackdump extern. Set + my_sendsig to indicate that signals are no longer available. + (my_readsig): Make Static again. + (sig_send): Interpret ERROR_BROKEN_PIPE as ESRCH. Remove special-case + EACCESS errno setting, just setting errno generally, even for "its_me" + case. + 2011-11-25 Christopher Faylor - * exceptions.cc (sigpacket::process): Move additional processing into... + * exceptions.cc (sigpacket::process): Move signal_exit processing + into... (_cygtls::signal_exit): ...here. Close my_readsig and comment on why. * pinfo.cc (pinfo::exit): Move sigproc_terminate earlier. Set exiting flag in lock_process. diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index b84a9fb35..5e6137ffd 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -279,7 +279,7 @@ stack_info::walk () return 1; } -static void +void stackdump (DWORD ebp, int open_file, bool isexception) { static bool already_dumped; @@ -1310,48 +1310,6 @@ exit_sig: use_tls->signal_exit (si.si_signo); /* never returns */ } -/* Cover function to `do_exit' to handle exiting even in presence of more - exceptions. We used to call exit, but a SIGSEGV shouldn't cause atexit - routines to run. */ -void -_cygtls::signal_exit (int rc) -{ - extern HANDLE my_readsig; - ForceCloseHandle (my_readsig); /* Disallow further signal sends */ - SetEvent (signal_arrived); /* Avoid potential deadlock with proc_lock */ - - if (rc == SIGQUIT || rc == SIGABRT) - { - CONTEXT c; - c.ContextFlags = CONTEXT_FULL; - GetThreadContext (hMainThread, &c); - copy_context (&c); - if (cygheap->rlim_core > 0UL) - rc |= 0x80; - } - - if (have_execed) - { - sigproc_printf ("terminating captive process"); - TerminateProcess (ch_spawn, sigExeced = rc); - } - - signal_debugger (rc & 0x7f); - if ((rc & 0x80) && !try_to_debug ()) - stackdump (thread_context.ebp, 1, 1); - - lock_process until_exit (true); - if (have_execed || exit_state > ES_PROCESS_LOCKED) - myself.exit (rc); - - /* Starve other threads in a vain attempt to stop them from doing something - stupid. */ - SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL); - - sigproc_printf ("about to call do_exit (%x)", rc); - do_exit (rc); -} - void events_init () { diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index e834f0bc6..fac5088a6 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -64,7 +64,7 @@ Static muto sync_proc_subproc; // Control access to subproc stuff _cygtls NO_COPY *_sig_tls; Static HANDLE my_sendsig; -HANDLE NO_COPY my_readsig; +Static HANDLE my_readsig; /* Function declarations */ static int __stdcall checkstate (waitq *) __attribute__ ((regparm (1))); @@ -365,6 +365,50 @@ _cygtls::remove_wq (DWORD wait) } } +/* Cover function to `do_exit' to handle exiting even in presence of more + exceptions. We used to call exit, but a SIGSEGV shouldn't cause atexit + routines to run. */ +void +_cygtls::signal_exit (int rc) +{ + extern void stackdump (DWORD, int, bool); + + my_sendsig = NULL; /* Make no_signals_allowed return true */ + ForceCloseHandle (my_readsig); /* Stop any currently executing sig_sends */ + SetEvent (signal_arrived); /* Avoid potential deadlock with proc_lock */ + + if (rc == SIGQUIT || rc == SIGABRT) + { + CONTEXT c; + c.ContextFlags = CONTEXT_FULL; + GetThreadContext (hMainThread, &c); + copy_context (&c); + if (cygheap->rlim_core > 0UL) + rc |= 0x80; + } + + if (have_execed) + { + sigproc_printf ("terminating captive process"); + TerminateProcess (ch_spawn, sigExeced = rc); + } + + signal_debugger (rc & 0x7f); + if ((rc & 0x80) && !try_to_debug ()) + stackdump (thread_context.ebp, 1, 1); + + lock_process until_exit (true); + if (have_execed || exit_state > ES_PROCESS_LOCKED) + myself.exit (rc); + + /* Starve other threads in a vain attempt to stop them from doing something + stupid. */ + SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL); + + sigproc_printf ("about to call do_exit (%x)", rc); + do_exit (rc); +} + /* Terminate the wait_subproc thread. Called on process exit. Also called by spawn_guts to disassociate any subprocesses from this @@ -682,7 +726,6 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls) process is exiting. */ if (!its_me) { - __seterrno (); sigproc_printf ("WriteFile for pipe %p failed, %E", sendsig); ForceCloseHandle (sendsig); } @@ -693,8 +736,11 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls) else if (!p->exec_sendsig) system_printf ("error sending signal %d to pid %d, pipe handle %p, %E", si.si_signo, p->pid, sendsig); - set_errno (EACCES); } + if (GetLastError () == ERROR_BROKEN_PIPE) + set_errno (ESRCH); + else + __seterrno (); goto out; } -- 2.43.5