summaryrefslogtreecommitdiff
path: root/lib/tests
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2020-02-02 18:54:22 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2020-02-05 20:45:07 +0000
commit497e13d2b4c1053bcd01bd15739fef55e7694a03 (patch)
treef23a158ae9246e1fcb9b828c24d7978d4e95344b /lib/tests
parent582ac086d6931f23935fa2301ace46cd82c043e2 (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.c45
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! */
}