|
From: <sv...@va...> - 2009-05-01 05:23:22
|
Author: njn
Date: 2009-05-01 06:23:08 +0100 (Fri, 01 May 2009)
New Revision: 9707
Log:
Merged r9706 (async-sigs clean-ups) from the trunk.
Removed:
branches/DARWIN/none/tests/async-sigs.stdout.exp
Modified:
branches/DARWIN/none/tests/Makefile.am
branches/DARWIN/none/tests/async-sigs.c
branches/DARWIN/none/tests/async-sigs.stderr.exp
branches/DARWIN/none/tests/async-sigs.vgtest
Modified: branches/DARWIN/none/tests/Makefile.am
===================================================================
--- branches/DARWIN/none/tests/Makefile.am 2009-05-01 05:00:34 UTC (rev 9706)
+++ branches/DARWIN/none/tests/Makefile.am 2009-05-01 05:23:08 UTC (rev 9707)
@@ -38,7 +38,7 @@
EXTRA_DIST = $(noinst_SCRIPTS) \
ansi.stderr.exp ansi.vgtest \
args.stderr.exp args.stdout.exp args.vgtest \
- async-sigs.stderr.exp async-sigs.stdout.exp async-sigs.vgtest \
+ async-sigs.stderr.exp async-sigs.vgtest \
bitfield1.stderr.exp bitfield1.vgtest \
bug129866.vgtest bug129866.stderr.exp bug129866.stdout.exp \
closeall.stderr.exp closeall.vgtest \
Modified: branches/DARWIN/none/tests/async-sigs.c
===================================================================
--- branches/DARWIN/none/tests/async-sigs.c 2009-05-01 05:00:34 UTC (rev 9706)
+++ branches/DARWIN/none/tests/async-sigs.c 2009-05-01 05:23:08 UTC (rev 9707)
@@ -1,3 +1,12 @@
+// This tests handling of signals sent from outside the process in the
+// following combinations: sync and async signals, caught and uncaught
+// signals, and while blocking or not blocking in a syscall. This exercises
+// various different paths in Valgrind's signal handling.
+//
+// It does this by installing signal handlers for one signal S, spawning
+// another process P, sending S from P multiple times (all caught), then
+// sending another signal from P (not caught).
+
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
@@ -7,7 +16,7 @@
#include <errno.h>
#include <time.h>
-static const struct timespec bip = { 0, 1000000000 / 5 };
+static const struct timespec bip = { 0, 1000000000 / 5 }; // 0.2 seconds.
static void handler(int sig)
{
@@ -18,103 +27,113 @@
respect to thread scheduling. */
static void do_kill(int pid, int sig)
{
- int status;
- int killer;
- int ret;
+ int status;
+ int killer;
+ int ret;
- killer = vfork();
-
- if (killer == -1) {
- perror("killer/vfork");
- exit(1);
- }
+ killer = vfork();
+ if (killer == -1) {
+ perror("killer/vfork");
+ exit(1);
+ }
- if (killer == 0) {
- char sigbuf[20];
- char pidbuf[20];
- sprintf(sigbuf, "-%d", sig);
- sprintf(pidbuf, "%d", pid);
- execl("/bin/kill", "kill", sigbuf, pidbuf, NULL);
- perror("exec failed");
- exit(1);
- }
+ // In the child, exec 'kill' in order to send the signal.
+ if (killer == 0) {
+ char sigbuf[20];
+ char pidbuf[20];
+ sprintf(sigbuf, "-%d", sig);
+ sprintf(pidbuf, "%d", pid);
+ execl("/bin/kill", "kill", sigbuf, pidbuf, NULL);
+ perror("exec failed");
+ exit(1);
+ }
- do
- ret = waitpid(killer, &status, 0);
- while(ret == -1 && errno == EINTR);
+ // In the parent, just wait for the child and then check it ran ok.
+ do
+ ret = waitpid(killer, &status, 0);
+ while (ret == -1 && errno == EINTR);
- if (ret != killer) {
- perror("kill/waitpid");
- exit(1);
- }
+ if (ret != killer) {
+ perror("kill/waitpid");
+ exit(1);
+ }
- if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
- printf("kill %d failed status=%s %d\n", killer,
- WIFEXITED(status) ? "exit" : "signal",
- WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status));
- exit(1);
- }
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+ fprintf(stderr, "kill %d failed status=%s %d\n", killer,
+ WIFEXITED(status) ? "exit" : "signal",
+ WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status));
+ exit(1);
+ }
}
static void test(int block, int caughtsig, int fatalsig)
{
- int pid;
- int status;
- int i;
+ int pid;
+ int status;
+ int i;
- printf("testing: blocking=%d caught=%d fatal=%d... ", block, caughtsig, fatalsig);
- fflush(stdout);
+ fprintf(stderr, "testing: blocking=%d caught=%d fatal=%d... ",
+ block, caughtsig, fatalsig);
- pid = fork();
- if (pid == -1) {
- perror("fork");
- exit(1);
- }
+ pid = fork();
+ if (pid == -1) {
+ perror("fork");
+ exit(1);
+ }
- if (pid == 0) {
- alarm(10); /* if something breaks, don't spin forever */
- signal(caughtsig, handler);
+ // In the child, install the signal handler, then wait for the signal to
+ // arrive:
+ // - if 'block' is set, wait on a system call;
+ // - otherwise, wait in client code (by spinning).
+ // The alarm() calls is so that if something breaks, we don't get stuck.
+ if (pid == 0) {
+ signal(caughtsig, handler);
+ alarm(10);
- for(;;)
- if (block)
- pause();
+ for (;;)
+ if (block) {
+ pause();
+ }
+ }
- }
+ // In the parent, send the signals.
+ nanosleep(&bip, 0); // Wait for child to get going.
- nanosleep(&bip, 0); /* wait for child to get going */
+ for (i = 0; i < 5; i++) {
+ do_kill(pid, caughtsig); // Should be caught.
+ nanosleep(&bip, 0);
+ do_kill(pid, caughtsig); // Ditto.
+ do_kill(pid, caughtsig); // Ditto.
+ }
- for(i = 0; i < 5; i++) {
- do_kill(pid, caughtsig); /* should be caught */
- nanosleep(&bip, 0);
- do_kill(pid, caughtsig);
- do_kill(pid, caughtsig);
- }
+ nanosleep(&bip, 0);
- nanosleep(&bip, 0);
+ do_kill(pid, fatalsig); // Should kill it.
+
+ // Check that the child behaved as expected when it received the signals.
+ if (waitpid(pid, &status, 0) != pid) {
+ fprintf(stderr, "FAILED: waitpid failed: %s\n", strerror(errno));
- do_kill(pid, fatalsig); /* should kill it */
-
- if (waitpid(pid, &status, 0) != pid)
- printf("FAILED: waitpid failed: %s\n", strerror(errno));
- else if (!WIFSIGNALED(status) || WTERMSIG(status) != fatalsig)
- printf("FAILED: child exited with unexpected status %s %d\n",
- WIFEXITED(status) ? "exit" : "signal",
- WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status));
- else
- printf("PASSED\n");
+ } else if (!WIFSIGNALED(status) || WTERMSIG(status) != fatalsig) {
+ fprintf(stderr, "FAILED: child exited with unexpected status %s %d\n",
+ WIFEXITED(status) ? "exit" : "signal",
+ WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status));
+
+ } else {
+ fprintf(stderr, "PASSED\n");
+ }
}
int main()
{
- static const int catch[] = { SIGSEGV, SIGUSR1 };
- static const int fatal[] = { SIGBUS, SIGUSR2 };
- int block, catchidx, fatalidx;
+ test(/*non-blocked*/0, /* sync*/SIGSEGV, /* sync*/SIGBUS);
+ test(/*non-blocked*/0, /* sync*/SIGSEGV, /*async*/SIGHUP);
+ test(/*non-blocked*/0, /*async*/SIGUSR1, /* sync*/SIGBUS);
+ test(/*non-blocked*/0, /*async*/SIGUSR1, /*async*/SIGHUP);
+ test(/* blocked*/1, /* sync*/SIGSEGV, /* sync*/SIGBUS);
+ test(/* blocked*/1, /* sync*/SIGSEGV, /*async*/SIGHUP);
+ test(/* blocked*/1, /*async*/SIGUSR1, /* sync*/SIGBUS);
+ test(/* blocked*/1, /*async*/SIGUSR1, /*async*/SIGHUP);
- setvbuf(stdout, NULL, _IOLBF, 0);
-
- for(block = 0; block < 2; block++)
- for(catchidx = 0; catchidx < sizeof(catch)/sizeof(*catch); catchidx++)
- for(fatalidx = 0; fatalidx < sizeof(fatal)/sizeof(*fatal); fatalidx++)
- test(block, catch[catchidx], fatal[fatalidx]);
- return 0;
+ return 0;
}
Modified: branches/DARWIN/none/tests/async-sigs.stderr.exp
===================================================================
--- branches/DARWIN/none/tests/async-sigs.stderr.exp 2009-05-01 05:00:34 UTC (rev 9706)
+++ branches/DARWIN/none/tests/async-sigs.stderr.exp 2009-05-01 05:23:08 UTC (rev 9707)
@@ -1,10 +1,8 @@
-
-
-
-
-
-
-
-
-
-
+testing: blocking=0 caught=11 fatal=7... PASSED
+testing: blocking=0 caught=11 fatal=1... PASSED
+testing: blocking=0 caught=10 fatal=7... PASSED
+testing: blocking=0 caught=10 fatal=1... PASSED
+testing: blocking=1 caught=11 fatal=7... PASSED
+testing: blocking=1 caught=11 fatal=1... PASSED
+testing: blocking=1 caught=10 fatal=7... PASSED
+testing: blocking=1 caught=10 fatal=1... PASSED
Deleted: branches/DARWIN/none/tests/async-sigs.stdout.exp
===================================================================
--- branches/DARWIN/none/tests/async-sigs.stdout.exp 2009-05-01 05:00:34 UTC (rev 9706)
+++ branches/DARWIN/none/tests/async-sigs.stdout.exp 2009-05-01 05:23:08 UTC (rev 9707)
@@ -1,8 +0,0 @@
-testing: blocking=0 caught=11 fatal=7... PASSED
-testing: blocking=0 caught=11 fatal=12... PASSED
-testing: blocking=0 caught=10 fatal=7... PASSED
-testing: blocking=0 caught=10 fatal=12... PASSED
-testing: blocking=1 caught=11 fatal=7... PASSED
-testing: blocking=1 caught=11 fatal=12... PASSED
-testing: blocking=1 caught=10 fatal=7... PASSED
-testing: blocking=1 caught=10 fatal=12... PASSED
Modified: branches/DARWIN/none/tests/async-sigs.vgtest
===================================================================
--- branches/DARWIN/none/tests/async-sigs.vgtest 2009-05-01 05:00:34 UTC (rev 9706)
+++ branches/DARWIN/none/tests/async-sigs.vgtest 2009-05-01 05:23:08 UTC (rev 9707)
@@ -1 +1,2 @@
prog: async-sigs
+vgopts: -q
|