From 2e070f114ce57555f00e62538b3b72ea97ca960c Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Sun, 22 Jan 2012 20:29:15 +0400 Subject: [PATCH] zdtm: Test for zombie tasks Test that 2 different exit()-ed zombies and 2 killed with different signals are handled properly. Signed-off-by: Pavel Emelyanov Signed-off-by: Cyrill Gorcunov --- test/zdtm.sh | 1 + test/zdtm/live/static/zombie00.c | 89 ++++++++++++++++++++++++-------- 2 files changed, 68 insertions(+), 22 deletions(-) diff --git a/test/zdtm.sh b/test/zdtm.sh index 24c74a305..5e6ee4f65 100644 --- a/test/zdtm.sh +++ b/test/zdtm.sh @@ -23,6 +23,7 @@ $ZP/streaming/pipe_loop00 $ZP/streaming/pipe_shared00 $ZP/transition/file_read $ZP/transition/fork +$ZP/static/zombie00 $ZP/static/socket_listen" CRTOOLS=`pwd`/`dirname $0`/../crtools diff --git a/test/zdtm/live/static/zombie00.c b/test/zdtm/live/static/zombie00.c index 466e39797..fb34d4ec2 100644 --- a/test/zdtm/live/static/zombie00.c +++ b/test/zdtm/live/static/zombie00.c @@ -11,40 +11,85 @@ const char *test_doc = "See if we can wait() for a zombified child after migration"; const char *test_author = "Roman Kagan "; +struct zombie { + int pid; + int exited; + int exitcode; +}; + +#define NR_ZOMBIES 4 + int main(int argc, char ** argv) { - int ret; - pid_t pid; + int i, status; + struct zombie zombie[NR_ZOMBIES]; + + zombie[0].exited = 1; + zombie[0].exitcode = 0; + + zombie[1].exited = 1; + zombie[1].exitcode = 3; + + zombie[2].exited = 0; + zombie[2].exitcode = SIGKILL; + + zombie[3].exited = 0; + zombie[3].exitcode = SIGSEGV; test_init(argc, argv); - pid = fork(); - if (pid < 0) { - err("fork failed: %m\n"); - exit(1); - } + for (i = 0; i < NR_ZOMBIES; i++) { + zombie[i].pid = fork(); + if (zombie[i].pid < 0) { + err("Fork failed %m\n"); + exit(1); + } - if (pid == 0) - _exit(0); + if (zombie[i].pid == 0) { + if (zombie[i].exited) + _exit(zombie[i].exitcode); + else if (zombie[i].exitcode == SIGSEGV) + *(int *)NULL = 0; + else + kill(getpid(), zombie[i].exitcode); + + _exit(13); /* just in case */ + } + + test_msg("kid %d will %d/%d\n", zombie[i].pid, + zombie[i].exited, zombie[i].exitcode); + } test_daemon(); test_waitsig(); - if (wait(&ret) != pid) { - fail("wait() returned wrong pid: %m\n"); - exit(1); - } - - if (WIFEXITED(ret)) { - ret = WEXITSTATUS(ret); - if (ret) { - fail("child exited with nonzero code %d (%s)\n", ret, strerror(ret)); + for (i = 0; i < NR_ZOMBIES; i++) { + if (waitpid(zombie[i].pid, &status, 0) != zombie[i].pid) { + fail("Exit with wrong pid\n"); exit(1); } - } - if (WIFSIGNALED(ret)) { - fail("child exited on unexpected signal %d\n", WTERMSIG(ret)); - exit(1); + + if (zombie[i].exited) { + if (!WIFEXITED(status)) { + fail("Not exited, but should (%d)\n", zombie[i].pid); + exit(1); + } + + if (WEXITSTATUS(status) != zombie[i].exitcode) { + fail("Exit with wrong status (%d)\n", zombie[i].pid); + exit(1); + } + } else { + if (!WIFSIGNALED(status)) { + fail("Not killed, but should (%d)\n", zombie[i].pid); + exit(1); + } + + if (WTERMSIG(status) != zombie[i].exitcode) { + fail("Killed with wrong signal (%d)\n", zombie[i].pid); + exit(1); + } + } } pass();