[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: abort() on Windows 2008 Server
From: |
Bruno Haible |
Subject: |
Re: abort() on Windows 2008 Server |
Date: |
Sat, 18 Oct 2008 23:37:53 +0200 |
User-agent: |
KMail/1.5.4 |
Hi Eric,
Thanks for the forward.
Ramiro Polla wrote:
> > The loop at sigprocmask.c:197 tests signal() on all signals up to NSIG
> > for SIG_ERR. On some version of Windows (I haven't checked which one,
> > but it affects Windows 2008 Server), a new signal has been added. It
> > is the SIGABRT_COMPAT signal, which is the same as SIGABRT [0]. So on
> > that loop, signal() is called twice for the same signal.
To be clear: The value of SIGABRT under native Windows, 22, has not changed.
The visible change is that <signal.h> of newer MSVS contains the line
#define SIGABRT_COMPAT 6
> > The abort() on sigprocmask.c:218 has the comment:
> > /* The application changed a signal handler while the signal
> > was blocked, bypassing our rpl_signal replacement.
> > We don't support this. */
> >
> > Actually you are changing it yourself. Once for signal 6 (which is the
> > value of SIGABRT_COMPAT), and then again for 22 (SIGABRT).
Thanks for this analysis. The sigset_t datatype introduced by gnulib has
to be adjusted. I propose this patch. Eric, what do you think?
2008-10-18 Bruno Haible <address@hidden>
* lib/sigprocmask.c (SIGABRT_COMPAT): New macro.
(sigismember, sigaddset, sigdelset, sigfillset, rpl_signal): Handle it
as an alias for SIGABRT.
* lib/sigaction.c (SIGABRT_COMPAT): New macro.
(sigaction): Map it to SIGABRT.
Reported by Ramiro Polla <address@hidden> via Eric Blake.
*** lib/sigprocmask.c.orig 2008-10-18 23:29:26.000000000 +0200
--- lib/sigprocmask.c 2008-10-18 23:24:48.000000000 +0200
***************
*** 43,48 ****
--- 43,56 ----
# define SIGSTOP (-1)
#endif
+ /* On native Windows, as of 2008, the signal SIGABRT_COMPAT is an alias
+ for the signal SIGABRT. Only one signal handler is stored for both
+ SIGABRT and SIGABRT_COMPAT. SIGABRT_COMPAT is not a signal of its own. */
+ #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ # undef SIGABRT_COMPAT
+ # define SIGABRT_COMPAT 6
+ #endif
+
typedef void (*handler_t) (int);
/* Handling of gnulib defined signals. */
***************
*** 74,80 ****
sigismember (const sigset_t *set, int sig)
{
if (sig >= 0 && sig < NSIG)
! return (*set >> sig) & 1;
else
return 0;
}
--- 82,95 ----
sigismember (const sigset_t *set, int sig)
{
if (sig >= 0 && sig < NSIG)
! {
! #ifdef SIGABRT_COMPAT
! if (sig == SIGABRT_COMPAT)
! sig = SIGABRT;
! #endif
!
! return (*set >> sig) & 1;
! }
else
return 0;
}
***************
*** 91,96 ****
--- 106,116 ----
{
if (sig >= 0 && sig < NSIG)
{
+ #ifdef SIGABRT_COMPAT
+ if (sig == SIGABRT_COMPAT)
+ sig = SIGABRT;
+ #endif
+
*set |= 1U << sig;
return 0;
}
***************
*** 106,111 ****
--- 126,136 ----
{
if (sig >= 0 && sig < NSIG)
{
+ #ifdef SIGABRT_COMPAT
+ if (sig == SIGABRT_COMPAT)
+ sig = SIGABRT;
+ #endif
+
*set &= ~(1U << sig);
return 0;
}
***************
*** 119,125 ****
int
sigfillset (sigset_t *set)
{
! *set = (2U << (NSIG - 1)) - 1;
return 0;
}
--- 144,154 ----
int
sigfillset (sigset_t *set)
{
! *set = ((2U << (NSIG - 1)) - 1)
! #ifdef SIGABRT_COMPAT
! & ~(1U << SIGABRT_COMPAT)
! #endif
! ;
return 0;
}
***************
*** 241,246 ****
--- 270,280 ----
if (sig >= 0 && sig < NSIG && sig != SIGKILL && sig != SIGSTOP
&& handler != SIG_ERR)
{
+ #ifdef SIGABRT_COMPAT
+ if (sig == SIGABRT_COMPAT)
+ sig = SIGABRT;
+ #endif
+
if (blocked_set & (1U << sig))
{
/* POSIX states that sigprocmask and signal are both
*** lib/sigaction.c.orig 2008-10-18 23:29:26.000000000 +0200
--- lib/sigaction.c 2008-10-18 23:27:42.000000000 +0200
***************
*** 64,69 ****
--- 64,77 ----
# define SIGSTOP (-1)
#endif
+ /* On native Windows, as of 2008, the signal SIGABRT_COMPAT is an alias
+ for the signal SIGABRT. Only one signal handler is stored for both
+ SIGABRT and SIGABRT_COMPAT. SIGABRT_COMPAT is not a signal of its own. */
+ #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ # undef SIGABRT_COMPAT
+ # define SIGABRT_COMPAT 6
+ #endif
+
/* A signal handler. */
typedef void (*handler_t) (int signal);
***************
*** 134,139 ****
--- 142,152 ----
return -1;
}
+ #ifdef SIGABRT_COMPAT
+ if (sig == SIGABRT_COMPAT)
+ sig = SIGABRT;
+ #endif
+
/* POSIX requires sigaction() to be async-signal-safe. In other
words, if an asynchronous signal can occur while we are anywhere
inside this function, the user's handler could then call