Path: blob/main/contrib/kyua/utils/process/executor_pid_test.cpp
48199 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2022 Dell Inc.4* Author: Eric van Gyzen5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND16* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE17* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE18* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE19* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL20* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS21* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)22* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT23* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY24* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF25* SUCH DAMAGE.26*/2728#if 029301. Run some "bad" tests that prevent kyua from removing the work directory.31We use "chflags uunlink". Mounting a file system from an md(4) device32is another common use case.332. Fork a lot, nearly wrapping the PID number space, so step 3 will re-use34a PID from step 1. Running the entire FreeBSD test suite is a more35realistic scenario for this step.363. Run some more tests. If the stars align, the bug is not fixed yet, and37kyua is built with debugging, kyua will abort with the following messages.38Without debugging, the tests in step 3 will reuse the context from step 1,39including stdout, stderr, and working directory, which are still populated40with stuff from step 1. When I found this bug, step 3 was41__test_cases_list__, which expects a certain format in stdout and failed42when it found something completely unrelated.434. You can clean up with: chflags -R nouunlink /tmp/kyua.*; rm -rf /tmp/kyua.*4445$ cc -o pid_wrap -latf-c pid_wrap.c46$ kyua test47pid_wrap:leak_0 -> passed [0.001s]48pid_wrap:leak_1 -> passed [0.001s]49pid_wrap:leak_2 -> passed [0.001s]50pid_wrap:leak_3 -> passed [0.001s]51pid_wrap:leak_4 -> passed [0.001s]52pid_wrap:leak_5 -> passed [0.001s]53pid_wrap:leak_6 -> passed [0.001s]54pid_wrap:leak_7 -> passed [0.001s]55pid_wrap:leak_8 -> passed [0.001s]56pid_wrap:leak_9 -> passed [0.001s]57pid_wrap:pid_wrap -> passed [1.113s]58pid_wrap:pid_wrap_0 -> passed [0.001s]59pid_wrap:pid_wrap_1 -> passed [0.001s]60pid_wrap:pid_wrap_2 -> passed [0.001s]61pid_wrap:pid_wrap_3 -> *** /usr/src/main/contrib/kyua/utils/process/executor.cpp:779: Invariant check failed: PID 60876 already in all_exec_handles; not properly cleaned up or reused too fast62*** Fatal signal 6 received63*** Log file is /home/vangyzen/.kyua/logs/kyua.20221006-193544.log64*** Please report this problem to kyua-discuss@googlegroups.com detailing what you were doing before the crash happened; if possible, include the log file mentioned above65Abort trap (core dumped)6667#endif6869#include <sys/stat.h>7071#include <atf-c++.hpp>7273#include <fcntl.h>74#include <signal.h>75#include <unistd.h>7677#include <cerrno>78#include <cstring>7980void81leak_work_dir()82{83int fd;8485ATF_REQUIRE((fd = open("unforgettable", O_CREAT|O_EXCL|O_WRONLY, 0600))86>= 0);87ATF_REQUIRE_EQ(0, fchflags(fd, UF_NOUNLINK));88ATF_REQUIRE_EQ(0, close(fd));89}9091void92wrap_pids()93{94pid_t begin, current, target;95bool wrapped;9697begin = getpid();98target = begin - 15;99if (target <= 1) {100target += 99999; // PID_MAX101wrapped = true;102} else {103wrapped = false;104}105106ATF_REQUIRE(signal(SIGCHLD, SIG_IGN) != SIG_ERR);107108do {109current = vfork();110if (current == 0) {111_exit(0);112}113ATF_REQUIRE(current != -1);114if (current < begin) {115wrapped = true;116}117} while (!wrapped || current < target);118}119120void121test_work_dir_reuse()122{123// If kyua is built with debugging, it would abort here before the fix.124}125126void127clean_up()128{129(void)system("chflags -R nouunlink ../..");130}131132ATF_TEST_CASE_WITHOUT_HEAD(leak_0);133ATF_TEST_CASE_BODY(leak_0) { leak_work_dir(); }134ATF_TEST_CASE_WITHOUT_HEAD(leak_1);135ATF_TEST_CASE_BODY(leak_1) { leak_work_dir(); }136ATF_TEST_CASE_WITHOUT_HEAD(leak_2);137ATF_TEST_CASE_BODY(leak_2) { leak_work_dir(); }138ATF_TEST_CASE_WITHOUT_HEAD(leak_3);139ATF_TEST_CASE_BODY(leak_3) { leak_work_dir(); }140ATF_TEST_CASE_WITHOUT_HEAD(leak_4);141ATF_TEST_CASE_BODY(leak_4) { leak_work_dir(); }142ATF_TEST_CASE_WITHOUT_HEAD(leak_5);143ATF_TEST_CASE_BODY(leak_5) { leak_work_dir(); }144ATF_TEST_CASE_WITHOUT_HEAD(leak_6);145ATF_TEST_CASE_BODY(leak_6) { leak_work_dir(); }146ATF_TEST_CASE_WITHOUT_HEAD(leak_7);147ATF_TEST_CASE_BODY(leak_7) { leak_work_dir(); }148ATF_TEST_CASE_WITHOUT_HEAD(leak_8);149ATF_TEST_CASE_BODY(leak_8) { leak_work_dir(); }150ATF_TEST_CASE_WITHOUT_HEAD(leak_9);151ATF_TEST_CASE_BODY(leak_9) { leak_work_dir(); }152153ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap);154ATF_TEST_CASE_BODY(pid_wrap) { wrap_pids(); }155156ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_0);157ATF_TEST_CASE_BODY(pid_wrap_0) { test_work_dir_reuse(); }158ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_1);159ATF_TEST_CASE_BODY(pid_wrap_1) { test_work_dir_reuse(); }160ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_2);161ATF_TEST_CASE_BODY(pid_wrap_2) { test_work_dir_reuse(); }162ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_3);163ATF_TEST_CASE_BODY(pid_wrap_3) { test_work_dir_reuse(); }164ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_4);165ATF_TEST_CASE_BODY(pid_wrap_4) { test_work_dir_reuse(); }166ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_5);167ATF_TEST_CASE_BODY(pid_wrap_5) { test_work_dir_reuse(); }168ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_6);169ATF_TEST_CASE_BODY(pid_wrap_6) { test_work_dir_reuse(); }170ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_7);171ATF_TEST_CASE_BODY(pid_wrap_7) { test_work_dir_reuse(); }172ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_8);173ATF_TEST_CASE_BODY(pid_wrap_8) { test_work_dir_reuse(); }174ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_9);175ATF_TEST_CASE_BODY(pid_wrap_9) { test_work_dir_reuse(); }176177ATF_TEST_CASE_WITHOUT_HEAD(really_clean_up);178ATF_TEST_CASE_BODY(really_clean_up) { clean_up(); }179180ATF_INIT_TEST_CASES(tcs)181{182ATF_ADD_TEST_CASE(tcs, leak_0);183ATF_ADD_TEST_CASE(tcs, leak_1);184ATF_ADD_TEST_CASE(tcs, leak_2);185ATF_ADD_TEST_CASE(tcs, leak_3);186ATF_ADD_TEST_CASE(tcs, leak_4);187ATF_ADD_TEST_CASE(tcs, leak_5);188ATF_ADD_TEST_CASE(tcs, leak_6);189ATF_ADD_TEST_CASE(tcs, leak_7);190ATF_ADD_TEST_CASE(tcs, leak_8);191ATF_ADD_TEST_CASE(tcs, leak_9);192193ATF_ADD_TEST_CASE(tcs, pid_wrap);194195ATF_ADD_TEST_CASE(tcs, pid_wrap_0);196ATF_ADD_TEST_CASE(tcs, pid_wrap_1);197ATF_ADD_TEST_CASE(tcs, pid_wrap_2);198ATF_ADD_TEST_CASE(tcs, pid_wrap_3);199ATF_ADD_TEST_CASE(tcs, pid_wrap_4);200ATF_ADD_TEST_CASE(tcs, pid_wrap_5);201ATF_ADD_TEST_CASE(tcs, pid_wrap_6);202ATF_ADD_TEST_CASE(tcs, pid_wrap_7);203ATF_ADD_TEST_CASE(tcs, pid_wrap_8);204ATF_ADD_TEST_CASE(tcs, pid_wrap_9);205206ATF_ADD_TEST_CASE(tcs, really_clean_up);207}208209210