* cygtls.h (_cygtls::signal_exit): Delete from class.

* exception.h (cygwin_exception): New class.
(cygwin_exception::dumpstack): Declare new function.
(cygwin_exception::context): Ditto.
(cygwin_exception::dump_exception): Ditto.
* exceptions.cc (cygwin_exception::dump_exception): Move into cygwin_exception
class.  Accommodate new variable names.
(cygwin_exception::dumpstack): Ditto stackdump -> dumpstack.
(exception::handle): Move andreas processing earlier.  Defer signal processing
decisions to the signal thread where they belong.  Pass exception information
to sig_send via new siginfo_t si_cyg field.
(ctrl_c_handler): Wait for SIGHUP signal to be processed since it could cause a
process exit and we don't want races with thread exit lock.
(signal_exit): Move back here from sigproc.cc.  Modify arguments and remove
from sigpacket class.  Decide when to dump core based on signal type.
(sigpacket::process): Handle exiting signals in context of threads rather than
in the signal thread.  Signal debugger on non-Windows signals.  Remove
setup_signal_exit call.
* sigproc.cc (no_signals_available): Remove argument.
(signal_exit_code): Delete.
(close_my_readsig): Ditto.
(_cygtls::signal_exit): Move to exceptions.cc.
(sigproc_terminate): Don't attempt to terminate signal thread.
(setup_signal_exit): Delete.
(exit_thread): Use new si_cyg entry in siginfo_t.
(sig_send): Just use empty initializer for si.  Accommodate change in
no_signals_available argument.
(wait_sig): Remove attempt to "go asynchronous" on process exit.  Delete
__SIGEXIT handling.  Don't ever exit.
* sigproc.h: Remove __SIGEXIT from signal enum.  Renumber.
* include/cygwin/signal.h (siginfo_t): Add si_cyg entry.
This commit is contained in:
Christopher Faylor 2013-01-02 18:34:06 +00:00
parent 74f8546d6e
commit ca77b848e7
8 changed files with 3264 additions and 3282 deletions

File diff suppressed because it is too large Load Diff

3065
winsup/cygwin/ChangeLog-2012 Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* cygtls.h
Copyright 2003, 2004, 2005, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
Copyright 2003, 2004, 2005, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
@ -220,7 +220,6 @@ public:
__attribute__((regparm(3)));
bool inside_kernel (CONTEXT *);
void signal_exit (int) __attribute__ ((noreturn, regparm(2)));
void copy_context (CONTEXT *) __attribute__ ((regparm(2)));
void signal_debugger (int) __attribute__ ((regparm(2)));

View File

@ -1,6 +1,6 @@
/* exception.h
Copyright 2010, 2011, 2012 Red Hat, Inc.
Copyright 2010, 2011, 2012, 2013 Red Hat, Inc.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
@ -28,10 +28,15 @@ public:
~exception () __attribute__ ((always_inline)) { _except_list = save; }
};
void stackdump (DWORD, CONTEXT * = NULL, EXCEPTION_RECORD * = NULL);
extern void inline
stackdump (DWORD n, bool)
class cygwin_exception
{
stackdump (n, (CONTEXT *) 1);
}
DWORD ebp;
PCONTEXT ctx;
EXCEPTION_RECORD *e;
void dump_exception ();
public:
cygwin_exception (DWORD in_ebp, PCONTEXT in_ctx = NULL, EXCEPTION_RECORD *in_e = NULL):
ebp (in_ebp), ctx (in_ctx), e (in_e) {}
void dumpstack ();
PCONTEXT context () const {return ctx;}
};

View File

@ -1,7 +1,7 @@
/* exceptions.cc
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@ -163,8 +163,8 @@ open_stackdumpfile ()
/* Utilities for dumping the stack, etc. */
static void
dump_exception (EXCEPTION_RECORD *e, CONTEXT *in)
void
cygwin_exception::dump_exception ()
{
const char *exception_name = NULL;
@ -181,15 +181,15 @@ dump_exception (EXCEPTION_RECORD *e, CONTEXT *in)
}
if (exception_name)
small_printf ("Exception: %s at eip=%08x\r\n", exception_name, in->Eip);
small_printf ("Exception: %s at eip=%08x\r\n", exception_name, ctx->Eip);
else
small_printf ("Signal %d at eip=%08x\r\n", e->ExceptionCode, in->Eip);
small_printf ("Signal %d at eip=%08x\r\n", e->ExceptionCode, ctx->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);
ctx->Eax, ctx->Ebx, ctx->Ecx, ctx->Edx, ctx->Esi, ctx->Edi);
small_printf ("ebp=%08x esp=%08x program=%W, pid %u, thread %s\r\n",
in->Ebp, in->Esp, myself->progname, myself->pid, cygthread::name ());
ctx->Ebp, ctx->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);
ctx->SegCs, ctx->SegDs, ctx->SegEs, ctx->SegFs, ctx->SegGs, ctx->SegSs);
}
/* A class for manipulating the stack. */
@ -273,7 +273,7 @@ stack_info::walk ()
}
void
stackdump (DWORD ebp, PCONTEXT in, EXCEPTION_RECORD *e)
cygwin_exception::dumpstack ()
{
static bool already_dumped;
@ -283,11 +283,11 @@ stackdump (DWORD ebp, PCONTEXT in, EXCEPTION_RECORD *e)
open_stackdumpfile ();
if (e)
dump_exception (e, in);
dump_exception ();
int i;
thestack.init (ebp, 1, !in); /* Initialize from the input CONTEXT */
thestack.init (ebp, 1, !ctx); /* Initialize from the input CONTEXT */
small_printf ("Stack trace:\r\nFrame Function Args\r\n");
for (i = 0; i < 16 && thestack++; i++)
{
@ -349,7 +349,8 @@ cygwin_stackdump ()
CONTEXT c;
c.ContextFlags = CONTEXT_FULL;
GetThreadContext (GetCurrentThread (), &c);
stackdump (c.Ebp);
cygwin_exception exc (c.Ebp);
exc.dumpstack ();
}
#define TIME_TO_WAIT_FOR_DEBUGGER 10000
@ -484,7 +485,7 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void
if (exit_state || e->ExceptionFlags)
return 1;
siginfo_t si = {0};
siginfo_t si = {};
si.si_code = SI_KERNEL;
/* Coerce win32 value to posix value. */
switch (e->ExceptionCode)
@ -594,17 +595,12 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void
return 1;
}
if (me.andreas)
me.andreas->leave (); /* Return from a "san" caught fault */
debug_printf ("In cygwin_except_handler exception %p at %p sp %p", e->ExceptionCode, in->Eip, in->Esp);
debug_printf ("In cygwin_except_handler signal %d at %p", si.si_signo, in->Eip);
bool masked = !!(me.sigmask & SIGTOMASK (si.si_signo));
if (masked)
syscall_printf ("signal %d, masked %p", si.si_signo,
global_sigs[si.si_signo].sa_mask);
debug_printf ("In cygwin_except_handler calling %p",
global_sigs[si.si_signo].sa_handler);
DWORD *ebp = (DWORD *) in->Esp;
for (DWORD *bpend = (DWORD *) __builtin_frame_address (0); ebp > bpend; ebp--)
if (*ebp == in->SegCs && ebp[-1] == in->Eip)
@ -613,9 +609,6 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void
break;
}
if (me.andreas)
me.andreas->leave (); /* Return from a "san" caught fault */
me.copy_context (in);
/* Temporarily replace windows top level SEH with our own handler.
@ -623,63 +616,38 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void
will be removed automatically after our exception handler returns. */
_except_list->handler = handle;
if (masked
|| &me == _sig_tls
|| !cygwin_finished_initializing
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_DFL
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR)
/* Another exception could happen while tracing or while exiting.
Only do this once. */
if (recursed++)
system_printf ("Error while dumping state (probably corrupted stack)");
else if (!try_to_debug (0))
rtl_unwind (frame, e);
else
{
/* Print the exception to the console */
if (!myself->cygstarted)
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;
}
/* Another exception could happen while tracing or while exiting.
Only do this once. */
if (recursed++)
system_printf ("Error while dumping state (probably corrupted stack)");
else
{
if (try_to_debug (0))
{
debugging = true;
return 0;
}
rtl_unwind (frame, e);
if (cygheap->rlim_core > 0UL)
stackdump ((DWORD) ebp, in, e);
}
if ((NTSTATUS) e->ExceptionCode == STATUS_ACCESS_VIOLATION)
{
int error_code = 0;
if (si.si_code == SEGV_ACCERR) /* Address present */
error_code |= 1;
if (e->ExceptionInformation[0]) /* Write access */
error_code |= 2;
if (!me.inside_kernel (in)) /* User space */
error_code |= 4;
klog (LOG_INFO, "%s[%d]: segfault at %08x rip %08x rsp %08x error %d",
__progname, myself->pid,
e->ExceptionInformation[1], in->Eip, in->Esp,
error_code);
}
setup_signal_exit ((cygheap->rlim_core > 0UL ? 0x80 : 0) | si.si_signo);
debugging = true;
return 0;
}
si.si_addr = (si.si_signo == SIGSEGV || si.si_signo == SIGBUS
? (void *) e->ExceptionInformation[1]
: (void *) in->Eip);
si.si_errno = si.si_pid = si.si_uid = 0;
/* FIXME: Probably should be handled in sigpacket::process */
if ((NTSTATUS) e->ExceptionCode == STATUS_ACCESS_VIOLATION)
{
int error_code = 0;
if (si.si_code == SEGV_ACCERR) /* Address present */
error_code |= 1;
if (e->ExceptionInformation[0]) /* Write access */
error_code |= 2;
if (!me.inside_kernel (in)) /* User space */
error_code |= 4;
klog (LOG_INFO, "%s[%d]: segfault at %08x rip %08x rsp %08x error %d",
__progname, myself->pid, e->ExceptionInformation[1],
in->Eip, in->Esp, error_code);
}
cygwin_exception exc ((DWORD) ebp, in, e);
si.si_cyg = (void *) &exc;
si.si_addr = (void *) in->Eip;
me.incyg++;
sig_send (NULL, si, &me); // Signal myself
sig_send (NULL, si, &me); /* Signal myself */
me.incyg--;
e->ExceptionFlags = 0;
return 0;
@ -962,7 +930,7 @@ ctrl_c_handler (DWORD type)
list goad. */
if (global_sigs[SIGHUP].sa_handler != SIG_DFL)
{
sig_send (myself_nowait, SIGHUP);
sig_send (myself, SIGHUP);
return TRUE;
}
return FALSE;
@ -1115,6 +1083,59 @@ set_signal_mask (sigset_t& setmask, sigset_t newmask)
sig_dispatch_pending (true);
}
/* Exit due to a signal. Should only be called from the signal thread. */
extern "C" {
static void
signal_exit (int sig, siginfo_t *si)
{
debug_printf ("exiting due to signal %d", sig);
exit_state = ES_SIGNAL_EXIT;
if (have_execed)
{
sigproc_printf ("terminating captive process");
TerminateProcess (ch_spawn, sigExeced = sig);
}
if (cygheap->rlim_core > 0UL)
switch (sig)
{
case SIGABRT:
case SIGBUS:
case SIGFPE:
case SIGILL:
case SIGQUIT:
case SIGSEGV:
case SIGSYS:
case SIGTRAP:
case SIGXCPU:
case SIGXFSZ:
if (try_to_debug ())
break;
if (si->si_code != SI_USER && si->si_cyg)
((cygwin_exception *) si->si_cyg)->dumpstack ();
else
{
cygwin_exception exc (_my_tls.thread_context.ebp);
exc.dumpstack ();
}
break;
}
lock_process until_exit (true);
if (have_execed || exit_state > ES_PROCESS_LOCKED)
myself.exit (sig);
/* 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)", sig);
do_exit (sig);
}
} /* extern "C" */
int __stdcall
sigpacket::process ()
{
@ -1224,18 +1245,39 @@ sigpacket::process ()
stop:
handler = (void *) sig_handle_tty_stop;
thissig = dummy;
goto dosig;
exit_sig:
handler = (void *) signal_exit;
thissig.sa_flags |= SA_SIGINFO;
if (si.si_signo == SIGKILL)
goto dispatch_sig;
dosig:
if (ISSTATE (myself, PID_STOPPED) && !continue_now)
rc = -1; /* No signals delivered if stopped */
else
{
/* Dispatch to the appropriate function. */
sigproc_printf ("signal %d, signal handler %p", si.si_signo, handler);
rc = setup_handler (handler, thissig, tls);
continue_now = false;
rc = -1; /* No signals delivered if stopped */
goto done;
}
dispatch_sig:
/* Do stuff for gdb */
if (si.si_code == SI_USER || !si.si_cyg)
{
CONTEXT c;
c.ContextFlags = CONTEXT_FULL;
GetThreadContext (hMainThread, &c);
_my_tls.copy_context (&c);
/* Tell gdb that we got a signal. Presumably, gdb already noticed this
if we hit an exception. */
_my_tls.signal_debugger (si.si_signo);
}
/* Dispatch to the appropriate function. */
sigproc_printf ("signal %d, signal handler %p", si.si_signo, handler);
rc = setup_handler (handler, thissig, tls);
continue_now = false;
done:
if (continue_now)
{
@ -1245,10 +1287,6 @@ done:
sigproc_printf ("returning %d", rc);
return rc;
exit_sig:
sigproc_printf ("setting up for exit with signal %d", si.si_signo);
setup_signal_exit (si.si_signo);
return rc;
}
int

View File

@ -1,6 +1,6 @@
/* signal.h
Copyright 2004, 2005, 2006, 2011 Red Hat, Inc.
Copyright 2004, 2005, 2006, 2011, 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@ -127,8 +127,13 @@ typedef struct
clock_t si_stime; /* system time */
};
/* core dumping signals */
void *si_addr; /* faulting address */
__extension__ struct
{
/* core dumping signals */
void *si_addr; /* faulting address */
void *si_cyg; /* pointer to block containing
cygwin-special info */
};
};
} siginfo_t;
#pragma pack(pop)

View File

@ -1,7 +1,7 @@
/* sigproc.cc: inter/intra signal and sub process handler
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@ -31,7 +31,7 @@ details. */
#define WSSC 60000 // Wait for signal completion
#define WPSP 40000 // Wait for proc_subproc mutex
#define no_signals_available(x) (!my_sendsig || ((x) && myself->exitcode & EXITCODE_SET) || (&_my_tls == _sig_tls))
#define no_signals_available() (exit_state || (myself->exitcode & EXITCODE_SET) || (&_my_tls == _sig_tls))
/*
* Global variables
@ -61,7 +61,6 @@ _cygtls NO_COPY *_sig_tls;
Static HANDLE my_sendsig;
Static HANDLE my_readsig;
Static int signal_exit_code;
/* Function declarations */
static int __stdcall checkstate (waitq *) __attribute__ ((regparm (1)));
@ -354,53 +353,6 @@ _cygtls::remove_wq (DWORD wait)
}
}
inline void
close_my_readsig ()
{
HANDLE h;
if ((h = InterlockedExchangePointer (&my_readsig, NULL)))
ForceCloseHandle1 (h, my_readsig);
}
/* Exit due to a signal, even in presence of more exceptions. We used to just
call exit, but a SIGSEGV shouldn't cause atexit routines to run.
Should only be called from the signal thread. */
void
_cygtls::signal_exit (int rc)
{
signal_debugger (rc & 0x7f);
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);
}
if ((rc & 0x80) && !try_to_debug ())
stackdump (thread_context.ebp, true);
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
@ -523,36 +475,11 @@ sigproc_terminate (exit_states es)
exit_states prior_exit_state = exit_state;
exit_state = es;
if (!cygwin_finished_initializing)
sigproc_printf ("don't worry about signal thread");
/* nothing to do */;
else if (prior_exit_state >= ES_FINAL)
sigproc_printf ("already performed");
else
{
sigproc_printf ("entering");
sig_send (myself_nowait, __SIGEXIT);
proc_terminate (); // clean up process stuff
}
}
/* Set up stuff so that the signal thread will know that we are
exiting due to a signal. */
void
setup_signal_exit (int sig)
{
signal_exit_code = sig; /* Tell wait_sig() that we are exiting. */
exit_state = ES_SIGNAL_EXIT; /* Tell the rest of the world that we are exiting. */
if (&_my_tls != _sig_tls)
{
sigpacket sp = {};
sp.si.si_signo = __SIGEXIT;
DWORD len;
/* Write a packet to the wait_sig thread. It will eventuall cause
the process to exit too. So just wait for that to happen after
sending the packet. */
WriteFile (my_sendsig, &sp, sizeof (sp), &len, NULL);
Sleep (INFINITE);
}
proc_terminate (); // clean up process stuff
}
/* Exit the current thread very carefully.
@ -576,7 +503,7 @@ exit_thread (DWORD res)
}
ProtectHandle1 (h, exit_thread);
siginfo_t si = {__SIGTHREADEXIT, SI_KERNEL};
si.si_value.sival_ptr = h;
si.si_cyg = h;
lock_process for_now; /* May block indefinitely if we're exiting. */
if (exit_state)
{
@ -599,7 +526,7 @@ sig_send (_pinfo *p, int sig, _cygtls *tid)
/* nothing */;
else if (sig == __SIGFLUSH || sig == __SIGFLUSHFAST)
return 0;
else if (sig == __SIGNOHOLD || sig == __SIGEXIT)
else if (sig == __SIGNOHOLD)
{
SetEvent (sig_hold);
sigheld = false;
@ -611,10 +538,9 @@ sig_send (_pinfo *p, int sig, _cygtls *tid)
#endif
return -1;
}
siginfo_t si = {0};
siginfo_t si = {};
si.si_signo = sig;
si.si_code = SI_KERNEL;
si.si_pid = si.si_uid = si.si_errno = 0;
return sig_send (p, si, tid);
}
@ -648,7 +574,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
}
else
{
if (no_signals_available (si.si_signo != __SIGEXIT))
if (no_signals_available ())
{
set_errno (EAGAIN);
goto out; // Either exiting or not yet initializing
@ -778,7 +704,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
}
else
{
if (no_signals_available (true))
if (no_signals_available ())
sigproc_printf ("I'm going away now");
else if (!p->exec_sendsig)
system_printf ("error sending signal %d to pid %d, pipe handle %p, %E",
@ -818,7 +744,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
rc = 0; // Successful exit
else
{
if (!no_signals_available (true))
if (!no_signals_available ())
system_printf ("wait for sig_complete event failed, signal %d, rc %d, %E",
si.si_signo, rc);
set_errno (ENOSYS);
@ -1390,12 +1316,6 @@ wait_sig (VOID *)
WaitForSingleObject (sig_hold, INFINITE);
DWORD nb;
/* If signal_exit_code is set then we are shutting down due to a signal.
We'll exit this loop iff there is nothing more in the signal queue. */
if (signal_exit_code
&& (!PeekNamedPipe (my_readsig, NULL, 0, NULL, &nb, NULL) || !nb))
break;
pack.sigtls = NULL;
if (!ReadFile (my_readsig, &pack, sizeof (pack), &nb, NULL))
break;
@ -1415,8 +1335,9 @@ wait_sig (VOID *)
continue;
}
if (signal_exit_code && pack.si.si_signo > 0)
continue; /* No more real signals allowed */
/* Don't process signals when we start exiting */
if (exit_state && pack.si.si_signo)
continue;
sigset_t dummy_mask;
if (!pack.mask)
@ -1459,10 +1380,6 @@ wait_sig (VOID *)
clearwait = true;
}
break;
case __SIGEXIT:
my_sendsig = NULL;
sigproc_printf ("saw __SIGEXIT");
break; /* handle below */
case __SIGSETPGRP:
init_console_handler (true);
break;
@ -1475,7 +1392,7 @@ wait_sig (VOID *)
release the process lock which it held and close it's handle.
See cgf-000017 in DevNotes for more details.
*/
HANDLE h = (HANDLE) pack.si.si_value.sival_ptr;
HANDLE h = (HANDLE) pack.si.si_cyg;
DWORD res = WaitForSingleObject (h, 5000);
lock_process::force_release (pack.sigtls);
ForceCloseHandle1 (h, exit_thread);
@ -1519,20 +1436,5 @@ wait_sig (VOID *)
sigproc_printf ("signalling pack.wakeup %p", pack.wakeup);
SetEvent (pack.wakeup);
}
if (pack.si.si_signo == __SIGEXIT)
break;
}
sigproc_printf ("signal thread exiting");
my_sendsig = NULL; /* Make no_signals_allowed return true */
close_my_readsig (); /* Cause any sig_send's to stop */
if (signal_exit_code)
_my_tls.signal_exit (signal_exit_code);
/* Just wait for the process to go away. Otherwise, this thread's
exit value could be interpreted as the process exit value.
See cgf-000017 in DevNotes for more details. */
Sleep (INFINITE);
}

View File

@ -24,9 +24,8 @@ enum
__SIGFLUSHFAST = -(NSIG + 6),
__SIGHOLD = -(NSIG + 7),
__SIGNOHOLD = -(NSIG + 8),
__SIGEXIT = -(NSIG + 9),
__SIGSETPGRP = -(NSIG + 10),
__SIGTHREADEXIT = -(NSIG + 11)
__SIGSETPGRP = -(NSIG + 9),
__SIGTHREADEXIT = -(NSIG + 10)
};
#endif