[igt-dev] [PATCH i-g-t v3] lib: Kill residual children at the end of a subtest
Chris Wilson
chris at chris-wilson.co.uk
Mon Feb 3 13:11:27 UTC 2020
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 at chris-wilson.co.uk>
Cc: Petri Latvala <petri.latvala at intel.com>
---
lib/igt_core.c | 7 +++++++
lib/tests/igt_fork.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 52 insertions(+)
diff --git a/lib/igt_core.c b/lib/igt_core.c
index a0bf29408..510417934 100644
--- a/lib/igt_core.c
+++ b/lib/igt_core.c
@@ -1362,6 +1362,13 @@ static void exit_subtest(const char *result)
igt_terminate_spins();
+ /* If the subtest aborted, it may have left children behind */
+ for (int c = 0; c < num_test_children; c++) {
+ kill(test_children[c], SIGKILL);
+ waitpid(test_children[c], NULL, 0); /* don't leave zombies! */
+ }
+ num_test_children = 0;
+
if (!in_dynamic_subtest)
_igt_dynamic_tests_executed = -1;
diff --git a/lib/tests/igt_fork.c b/lib/tests/igt_fork.c
index 7e8b4f9b5..e30584fd2 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! */
}
--
2.25.0
More information about the igt-dev
mailing list