Date: Thu, 17 Oct 2013 10:31:58 +0300 From: Konstantin Belousov <kostikbel@gmail.com> To: Julio Merino <julio@meroh.net> Cc: ppc@freebsd.org Subject: Re: powerpc/183040: Nested signal handling is broken Message-ID: <20131017073158.GB3865@kib.kiev.ua> In-Reply-To: <201310162349.r9GNnDud012497@mastodon.meroh.net>
index | next in thread | previous in thread | raw e-mail
[-- Attachment #1 --]
On Wed, Oct 16, 2013 at 07:49:13PM -0400, Julio Merino wrote:
>
> >Number: 183040
> >Category: powerpc
> >Synopsis: Nested signal handling is broken
> >Confidential: no
> >Severity: serious
> >Priority: medium
> >Responsible: freebsd-ppc
> >State: open
> >Quarter:
> >Keywords:
> >Date-Required:
> >Class: sw-bug
> >Submitter-Id: current-users
> >Arrival-Date: Thu Oct 17 00:00:00 UTC 2013
> >Closed-Date:
> >Last-Modified:
> >Originator: Julio Merino
> >Release: FreeBSD 11.0-CURRENT powerpc
> >Organization:
> >Environment:
> System: FreeBSD mastodon.meroh.net 11.0-CURRENT FreeBSD 11.0-CURRENT #9 r256450M: Mon Oct 14 16:35:08 EDT 2013 jmmv@mastodon.meroh.net:/usr/obj/usr/src/sys/GENERIC64 powerpc
>
> Also affects FreeBSD 10.0 alphas.
>
>
> >Description:
> When programming a given signal twice in a nested manner, the
> unprogramming of the top-most signal handler does not properly
> restore the previous (non-default handler). In other words:
>
> program signal X
> program signal X
> deliver signal X to self -- custom handler runs
> unprogram signal X
> deliver signal X to self -- default handler runs or not delivered
> unprogram signal X
>
> Interestingly, things seem to work well for X = SIGTERM but not
> for X = SIGHUP nor X = SIGINT. I have not tested other signals.
>
> I have encountered this bug while running the kyua test suite
> on a powerpc64 machine (specifics detailed above) and noticing
> a couple of tests fail, which work well in other operating
> systems and in amd64. The test case below is derived form the
> code in kyua.
>
> Here is the output of the test program on an amd64 machine,
> which to my knowledge is working properly:
>
> SIGNAL 1
> Programming at level 1
> Programming at level 0
> Signal 1 caught correctly
> Unprogramming at level 0
> Signal 1 caught correctly
> Unprogramming at level 1
>
> SIGNAL 2
> Programming at level 1
> Programming at level 0
> Signal 2 caught correctly
> Unprogramming at level 0
> Signal 2 caught correctly
> Unprogramming at level 1
>
> SIGNAL 15
> Programming at level 1
> Programming at level 0
> Signal 15 caught correctly
> Unprogramming at level 0
> Signal 15 caught correctly
> Unprogramming at level 1
>
> The same test program yields this on powerpc64:
>
> SIGNAL 1
> Programming at level 1
> Programming at level 0
> Signal 1 caught correctly
> Unprogramming at level 0
> a.out: Signal 1 not caught
>
> >How-To-Repeat:
> Build and run this test program:
>
> -----
> #include <err.h>
> #include <signal.h>
> #include <stdbool.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
>
> static bool caught = false;
>
> static void
> handler(const int signo)
> {
> caught = true;
> }
>
> static void
> do_it(const int signo, const int level)
> {
> struct sigaction sa, old_sa;
>
> printf("Programming at level %d\n", level);
>
> sa.sa_handler = handler;
> sigemptyset(&sa.sa_mask);
> sa.sa_flags = SA_RESTART;
>
> if (sigaction(signo, &sa, &old_sa) == -1)
> err(EXIT_FAILURE, "sigaction program failed");
>
> if (level > 0)
> do_it(signo, level - 1);
>
> caught = false;
> kill(getpid(), signo);
> if (caught)
> printf("Signal %d caught correctly\n", signo);
> else
> errx(EXIT_FAILURE, "Signal %d not caught\n", signo);
>
> if (sigaction(signo, &old_sa, NULL) == -1)
> err(EXIT_FAILURE, "sigaction unprogram failed");
>
> printf("Unprogramming at level %d\n", level);
> }
>
> static void
> try_one_signal(const int signo, const int level)
> {
> printf("SIGNAL %d\n", signo);
> do_it(signo, level);
> printf("\n");
> }
>
> int
> main(void)
> {
> try_one_signal(SIGHUP, 1);
> try_one_signal(SIGINT, 1);
> try_one_signal(SIGTERM, 1);
> return EXIT_SUCCESS;
> }
What you could do, is to localize the point where the breakage occur.
Add a function like this:
static void
print_sig_disposition(int signo)
{
struct sigaction sa;
sigaction(signo, NULL, &sa);
printf("sig %d handler %p\n", signo, sa.sa_handler);
}
and sprinkle a calls to it often enough, to see where the reset of the
disposition happens. Insert the call to the function into the signal
handler as well.
[-- Attachment #2 --]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (FreeBSD)
iQIcBAEBAgAGBQJSX5JtAAoJEJDCuSvBvK1BaWoP/07mgLfpnYMMnQ0BbmjVwFYX
emwYOT3SCtHzr2wXqAVZTg598cj9y4raf7IZO+w71ywneJpeOG/Ymxw4eZE68sl5
lfV7oA/2jiPWQVxNCJ9XBscHr0m6e5Q+oQJqVL90zQfd/eJiyhrX8URuYbQsqZj2
BmSaF1z9PUXJJfXzlQsHe2zS0J+nHASt1YF81QAP/HWpzIhcQfs7dktzk2FqkBxR
Q+jGdhj36pcLXjU4dVcGQV2AWknvkQMHP3oZZXhm6KBjfcQ/pFwJnc9NSu4IATZ8
D+ogmKHinBsoP8ZAwf0NK1hoOn2HKzfnAOeWfelIcOISypPI3tRMQDEGh3yzoGRy
xFjV2y/NYSQ6gSDgAF7R+NSUcb1KEdTvmBaoeOFyxmLO27JkX/mlT7BJnZi7GDD0
tHn9CTi/G7mM0sXuCFD6Td+uJOG5nyrdq1eViiNjGVq4K4taqAfhwUlxG59uMILd
Q3YehhXQNUCSrRm+YP2id9AqRsTYaZGdnRXv94l5rI7+AhKmKe2TClVf5Lk23jPx
ShaIyBP6+S83onIrrqxICm4AYInN0KAmQuNt2QBphFNGuc52FK7LJEFJA6xQ0yQ7
/U4A2fnA1WHVmSu3xCJxOLrw9Pqby3uSNXhR7spITh9U4KNiFpLkKvF3DM8g0jhv
kiwpaKfg4jceS+yBPIsy
=NfKd
-----END PGP SIGNATURE-----
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20131017073158.GB3865>
