diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2020-02-02 18:54:22 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2020-02-05 20:45:07 +0000 |
commit | 497e13d2b4c1053bcd01bd15739fef55e7694a03 (patch) | |
tree | f23a158ae9246e1fcb9b828c24d7978d4e95344b /lib/tests | |
parent | 582ac086d6931f23935fa2301ace46cd82c043e2 (diff) |
lib: Kill residual children at the end of a subtest
Ensure that we tidy up all the excess children left behind by a failing
subtest, we do not want them loitering into the next!
v2: Behead the undead plague, and throw in a bonus lib/tests
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Petri Latvala <petri.latvala@intel.com>
Reviewed-by: Petri Latvala <petri.latvala@intel.com>
Diffstat (limited to 'lib/tests')
-rw-r--r-- | lib/tests/igt_fork.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/lib/tests/igt_fork.c b/lib/tests/igt_fork.c index 7e8b4f9b..e30584fd 100644 --- a/lib/tests/igt_fork.c +++ b/lib/tests/igt_fork.c @@ -107,6 +107,48 @@ static int do_fork(void (*test_to_run)(void)) } } +static int do_subtest(void (*test_to_run)(void)) +{ + int pid, status; + int argc; + + switch (pid = fork()) { + case -1: + internal_assert(0); + case 0: + argc = ARRAY_SIZE(argv_run); + igt_subtest_init(argc, argv_run); + test_to_run(); + igt_exit(); + default: + while (waitpid(pid, &status, 0) == -1 && + errno == EINTR) + ; + + return status; + } +} + +static void subtest_leak(void) +{ + pid_t *children = + mmap(0, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); + const int num_children = 4096 / sizeof(*children); + + igt_subtest("fork-leak") { + igt_fork(child, num_children) + children[child] = getpid(); + + /* leak the children */ + igt_assert(0); + } + + /* We expect the exit_subtest to cleanup after the igt_fork */ + for (int i = 0; i < num_children; i++) + assert(kill(children[i], 0) == -1 && errno == ESRCH); + + munmap(children, 4096); +} int main(int argc, char **argv) { @@ -131,4 +173,7 @@ int main(int argc, char **argv) /* check that any other process leaks are caught*/ ret = do_fork(plain_fork_leak); internal_assert_wsignaled(ret, SIGABRT); + + ret = do_subtest(subtest_leak); + internal_assert_wexited(ret, IGT_EXIT_FAILURE); /* not asserted! */ } |