powerpc/183040: Nested signal handling is broken
Konstantin Belousov
kostikbel at gmail.com
Thu Oct 17 07:32:04 UTC 2013
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 at 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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 834 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-ppc/attachments/20131017/97790986/attachment.sig>
More information about the freebsd-ppc
mailing list