Julian Seward 7c542ccd39 Add new files resulting from merging in the 2.4.0 line. Many of these
seem to be simply duplication of the x86 instruction set tests into
the addrcheck and helgrind trees.  I'm not sure what this duplication
achieves.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3264
2005-03-10 23:23:45 +00:00

120 lines
2.6 KiB
C

#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
static const struct timespec bip = { 0, 1000000000 / 5 };
static void handler(int sig)
{
}
/* Kill our child, but use a separate kill command. This is so that
it's running independently of Valgrind, and so is async with
respect to thread scheduling. */
static void do_kill(int pid, int sig)
{
int status;
int killer;
int ret;
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);
}
do
ret = waitpid(killer, &status, 0);
while(ret == -1 && errno == EINTR);
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);
}
}
static void test(int block, int caughtsig, int fatalsig)
{
int pid;
int status;
int i;
printf("testing: blocking=%d caught=%d fatal=%d... ", block, caughtsig, fatalsig);
fflush(stdout);
pid = fork();
if (pid == -1) {
perror("fork");
exit(1);
}
if (pid == 0) {
signal(caughtsig, handler);
for(;;)
if (block)
pause();
}
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);
do_kill(pid, caughtsig);
}
nanosleep(&bip, 0);
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");
}
int main()
{
static const int catch[] = { SIGSEGV, SIGUSR1 };
static const int fatal[] = { SIGBUS, SIGUSR2 };
int block, catchidx, fatalidx;
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;
}