From: Marco Atzeri <marco.atzeri@gmail.com>
To: cygwin-developers@cygwin.com
Subject: Signal delivered while blocked
Date: Mon, 27 Dec 2021 05:51:37 +0100 [thread overview]
Message-ID: <2e5e006e-256d-17af-fbd5-2f38fce19b7c@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 257 bytes --]
Hi Guys,
Some time ago (2017) a Postgres developer reported a signal issue
not present in older version (2013)
https://sourceware.org/pipermail/cygwin/2017-August/234001.html
For what I can see the issue is still present.
Ideas for debugging ?
Marco
[-- Attachment #2: sigprocmask-exclusion.c --]
[-- Type: text/plain, Size: 3190 bytes --]
/*
* Demonstrate improper delivery of a blocked signal.
*
* This program prints "ERROR: already forbidden" and aborts within one
* second on this configuration (uname -srvm):
* CYGWIN_NT-10.0 2.7.0(0.306/5/3) 2017-02-12 13:18 x86_64
*
* It runs indefinitely (>600s) without trouble on these configurations:
* CYGWIN_NT-6.0 1.7.27(0.271/5/3) 2013-12-09 11:57 i686
* Linux 3.10.0-514.16.1.el7.x86_64 #1 SMP Wed Apr 12 15:04:24 UTC 2017 x86_64 [CentOS 7]
* AIX 7100-03-02-1412
* SunOS 5.10 Generic_147147-26 sun4u
*/
#include <setjmp.h>
#include <signal.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static sigset_t block, unblock;
static sig_atomic_t sigblocked = 0; /* Have I blocked signals? */
static char *stack_base;
static sigjmp_buf jmp;
static void
sigforbid(void)
{
const char errmsg[] = "ERROR: already forbidden\n";
if (sigprocmask(SIG_SETMASK, &block, NULL) != 0)
perror("sigprocmask");
if (sigblocked == 1)
{
write(2, errmsg, sizeof(errmsg) - 1);
abort();
}
sigblocked = 1;
}
static void
sigpermit(void)
{
const char errmsg[] = "ERROR: already permitted\n";
if (sigblocked == 0)
{
write(2, errmsg, sizeof(errmsg) - 1);
abort();
}
sigblocked = 0;
if (sigprocmask(SIG_SETMASK, &unblock, NULL) != 0)
perror("sigprocmask");
}
/*
* Start fresh in main() when the stack gets too deep. This is not essential
* to the test, but it allows for long runs without huge RLIMIT_STACK.
*/
static void
clear_stack_if_needed(void)
{
char stack_position;
ptrdiff_t stack_usage;
stack_usage = stack_base - &stack_position;
if (stack_usage < 0)
stack_usage = -stack_usage;
if (stack_usage > 1024 * 1024)
{
puts("releasing excess stack");
sigblocked = 1;
siglongjmp(jmp, 1);
}
}
static void
handler(int arg)
{
sigforbid();
clear_stack_if_needed();
/* wait for extra signal to arrive, after 1-2ms */
usleep(5000);
sigpermit();
}
int main(int argc, char **argv)
{
char stack_position;
/* initial signal mask setup */
sigemptyset(&unblock);
sigfillset(&block);
sigdelset(&block, SIGTRAP);
sigdelset(&block, SIGABRT);
sigdelset(&block, SIGILL);
sigdelset(&block, SIGFPE);
sigdelset(&block, SIGSEGV);
sigdelset(&block, SIGBUS);
sigdelset(&block, SIGSYS);
sigdelset(&block, SIGCONT);
sigforbid();
/* Register signal handlers. Problem somehow requires two signals. */
{
struct sigaction act, oact;
act.sa_handler = handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if (sigaction(SIGUSR1, &act, &oact) != 0)
perror("sigaction");
if (sigaction(SIGCHLD, &act, &oact) != 0)
perror("sigaction");
}
/* start a child to inundate me with signals */
{
pid_t pid, ppid;
pid = fork();
switch (pid)
{
case -1:
perror("fork");
return 1;
case 0:
ppid = getppid();
printf("pid=%d inundating pid=%d with SIGUSR1 and SIGCHLD\n",
getpid(), ppid);
while (kill(ppid, random() % 2 ? SIGUSR1 : SIGCHLD) == 0)
;
puts("child done");
return 0;
}
}
/* loop forever while we receive signals */
stack_base = &stack_position;
sigsetjmp(jmp, 1);
for (;;)
{
sigpermit();
usleep(1000);
sigforbid();
}
}
next reply other threads:[~2021-12-27 4:51 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-27 4:51 Marco Atzeri [this message]
2021-12-27 23:14 ` David McFarland
2021-12-28 2:46 ` Marco Atzeri
2021-12-28 13:41 ` Z. Majeed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2e5e006e-256d-17af-fbd5-2f38fce19b7c@gmail.com \
--to=marco.atzeri@gmail.com \
--cc=cygwin-developers@cygwin.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).