xref: /freebsd-src/contrib/kyua/utils/process/executor_pid_test.cpp (revision 6b13d60bf49ee40626d7e3a5d5a80519f0067307)
1*6b13d60bSMuhammad Moinur Rahman /*-
2*6b13d60bSMuhammad Moinur Rahman  * SPDX-License-Identifier: BSD-2-Clause
3*6b13d60bSMuhammad Moinur Rahman  *
4*6b13d60bSMuhammad Moinur Rahman  * Copyright (c) 2022 Dell Inc.
5*6b13d60bSMuhammad Moinur Rahman  * Author: Eric van Gyzen
6*6b13d60bSMuhammad Moinur Rahman  *
7*6b13d60bSMuhammad Moinur Rahman  * Redistribution and use in source and binary forms, with or without
8*6b13d60bSMuhammad Moinur Rahman  * modification, are permitted provided that the following conditions
9*6b13d60bSMuhammad Moinur Rahman  * are met:
10*6b13d60bSMuhammad Moinur Rahman  * 1. Redistributions of source code must retain the above copyright
11*6b13d60bSMuhammad Moinur Rahman  *    notice, this list of conditions and the following disclaimer.
12*6b13d60bSMuhammad Moinur Rahman  * 2. Redistributions in binary form must reproduce the above copyright
13*6b13d60bSMuhammad Moinur Rahman  *    notice, this list of conditions and the following disclaimer in the
14*6b13d60bSMuhammad Moinur Rahman  *    documentation and/or other materials provided with the distribution.
15*6b13d60bSMuhammad Moinur Rahman  *
16*6b13d60bSMuhammad Moinur Rahman  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*6b13d60bSMuhammad Moinur Rahman  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*6b13d60bSMuhammad Moinur Rahman  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*6b13d60bSMuhammad Moinur Rahman  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*6b13d60bSMuhammad Moinur Rahman  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*6b13d60bSMuhammad Moinur Rahman  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*6b13d60bSMuhammad Moinur Rahman  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*6b13d60bSMuhammad Moinur Rahman  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*6b13d60bSMuhammad Moinur Rahman  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*6b13d60bSMuhammad Moinur Rahman  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*6b13d60bSMuhammad Moinur Rahman  * SUCH DAMAGE.
27*6b13d60bSMuhammad Moinur Rahman  */
28*6b13d60bSMuhammad Moinur Rahman 
29*6b13d60bSMuhammad Moinur Rahman #if 0
30*6b13d60bSMuhammad Moinur Rahman 
31*6b13d60bSMuhammad Moinur Rahman 1. Run some "bad" tests that prevent kyua from removing the work directory.
32*6b13d60bSMuhammad Moinur Rahman    We use "chflags uunlink".  Mounting a file system from an md(4) device
33*6b13d60bSMuhammad Moinur Rahman    is another common use case.
34*6b13d60bSMuhammad Moinur Rahman 2. Fork a lot, nearly wrapping the PID number space, so step 3 will re-use
35*6b13d60bSMuhammad Moinur Rahman    a PID from step 1.  Running the entire FreeBSD test suite is a more
36*6b13d60bSMuhammad Moinur Rahman    realistic scenario for this step.
37*6b13d60bSMuhammad Moinur Rahman 3. Run some more tests.  If the stars align, the bug is not fixed yet, and
38*6b13d60bSMuhammad Moinur Rahman    kyua is built with debugging, kyua will abort with the following messages.
39*6b13d60bSMuhammad Moinur Rahman    Without debugging, the tests in step 3 will reuse the context from step 1,
40*6b13d60bSMuhammad Moinur Rahman    including stdout, stderr, and working directory, which are still populated
41*6b13d60bSMuhammad Moinur Rahman    with stuff from step 1.  When I found this bug, step 3 was
42*6b13d60bSMuhammad Moinur Rahman    __test_cases_list__, which expects a certain format in stdout and failed
43*6b13d60bSMuhammad Moinur Rahman    when it found something completely unrelated.
44*6b13d60bSMuhammad Moinur Rahman 4. You can clean up with: chflags -R nouunlink /tmp/kyua.*; rm -rf /tmp/kyua.*
45*6b13d60bSMuhammad Moinur Rahman 
46*6b13d60bSMuhammad Moinur Rahman $ cc -o pid_wrap -latf-c pid_wrap.c
47*6b13d60bSMuhammad Moinur Rahman $ kyua test
48*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_0  ->  passed  [0.001s]
49*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_1  ->  passed  [0.001s]
50*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_2  ->  passed  [0.001s]
51*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_3  ->  passed  [0.001s]
52*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_4  ->  passed  [0.001s]
53*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_5  ->  passed  [0.001s]
54*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_6  ->  passed  [0.001s]
55*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_7  ->  passed  [0.001s]
56*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_8  ->  passed  [0.001s]
57*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_9  ->  passed  [0.001s]
58*6b13d60bSMuhammad Moinur Rahman pid_wrap:pid_wrap  ->  passed  [1.113s]
59*6b13d60bSMuhammad Moinur Rahman pid_wrap:pid_wrap_0  ->  passed  [0.001s]
60*6b13d60bSMuhammad Moinur Rahman pid_wrap:pid_wrap_1  ->  passed  [0.001s]
61*6b13d60bSMuhammad Moinur Rahman pid_wrap:pid_wrap_2  ->  passed  [0.001s]
62*6b13d60bSMuhammad Moinur Rahman pid_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 fast
63*6b13d60bSMuhammad Moinur Rahman *** Fatal signal 6 received
64*6b13d60bSMuhammad Moinur Rahman *** Log file is /home/vangyzen/.kyua/logs/kyua.20221006-193544.log
65*6b13d60bSMuhammad Moinur Rahman *** 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 above
66*6b13d60bSMuhammad Moinur Rahman Abort trap (core dumped)
67*6b13d60bSMuhammad Moinur Rahman 
68*6b13d60bSMuhammad Moinur Rahman #endif
69*6b13d60bSMuhammad Moinur Rahman 
70*6b13d60bSMuhammad Moinur Rahman #include <sys/stat.h>
71*6b13d60bSMuhammad Moinur Rahman 
72*6b13d60bSMuhammad Moinur Rahman #include <atf-c++.hpp>
73*6b13d60bSMuhammad Moinur Rahman 
74*6b13d60bSMuhammad Moinur Rahman #include <fcntl.h>
75*6b13d60bSMuhammad Moinur Rahman #include <signal.h>
76*6b13d60bSMuhammad Moinur Rahman #include <unistd.h>
77*6b13d60bSMuhammad Moinur Rahman 
78*6b13d60bSMuhammad Moinur Rahman #include <cerrno>
79*6b13d60bSMuhammad Moinur Rahman #include <cstring>
80*6b13d60bSMuhammad Moinur Rahman 
81*6b13d60bSMuhammad Moinur Rahman void
leak_work_dir()82*6b13d60bSMuhammad Moinur Rahman leak_work_dir()
83*6b13d60bSMuhammad Moinur Rahman {
84*6b13d60bSMuhammad Moinur Rahman 	int fd;
85*6b13d60bSMuhammad Moinur Rahman 
86*6b13d60bSMuhammad Moinur Rahman 	ATF_REQUIRE((fd = open("unforgettable", O_CREAT|O_EXCL|O_WRONLY, 0600))
87*6b13d60bSMuhammad Moinur Rahman 	    >= 0);
88*6b13d60bSMuhammad Moinur Rahman 	ATF_REQUIRE_EQ(0, fchflags(fd, UF_NOUNLINK));
89*6b13d60bSMuhammad Moinur Rahman 	ATF_REQUIRE_EQ(0, close(fd));
90*6b13d60bSMuhammad Moinur Rahman }
91*6b13d60bSMuhammad Moinur Rahman 
92*6b13d60bSMuhammad Moinur Rahman void
wrap_pids()93*6b13d60bSMuhammad Moinur Rahman wrap_pids()
94*6b13d60bSMuhammad Moinur Rahman {
95*6b13d60bSMuhammad Moinur Rahman 	pid_t begin, current, target;
96*6b13d60bSMuhammad Moinur Rahman 	bool wrapped;
97*6b13d60bSMuhammad Moinur Rahman 
98*6b13d60bSMuhammad Moinur Rahman 	begin = getpid();
99*6b13d60bSMuhammad Moinur Rahman 	target = begin - 15;
100*6b13d60bSMuhammad Moinur Rahman 	if (target <= 1) {
101*6b13d60bSMuhammad Moinur Rahman 		target += 99999;    // PID_MAX
102*6b13d60bSMuhammad Moinur Rahman 		wrapped = true;
103*6b13d60bSMuhammad Moinur Rahman 	} else {
104*6b13d60bSMuhammad Moinur Rahman 		wrapped = false;
105*6b13d60bSMuhammad Moinur Rahman 	}
106*6b13d60bSMuhammad Moinur Rahman 
107*6b13d60bSMuhammad Moinur Rahman 	ATF_REQUIRE(signal(SIGCHLD, SIG_IGN) != SIG_ERR);
108*6b13d60bSMuhammad Moinur Rahman 
109*6b13d60bSMuhammad Moinur Rahman 	do {
110*6b13d60bSMuhammad Moinur Rahman 		current = vfork();
111*6b13d60bSMuhammad Moinur Rahman 		if (current == 0) {
112*6b13d60bSMuhammad Moinur Rahman 			_exit(0);
113*6b13d60bSMuhammad Moinur Rahman 		}
114*6b13d60bSMuhammad Moinur Rahman 		ATF_REQUIRE(current != -1);
115*6b13d60bSMuhammad Moinur Rahman 		if (current < begin) {
116*6b13d60bSMuhammad Moinur Rahman 			wrapped = true;
117*6b13d60bSMuhammad Moinur Rahman 		}
118*6b13d60bSMuhammad Moinur Rahman 	} while (!wrapped || current < target);
119*6b13d60bSMuhammad Moinur Rahman }
120*6b13d60bSMuhammad Moinur Rahman 
121*6b13d60bSMuhammad Moinur Rahman void
test_work_dir_reuse()122*6b13d60bSMuhammad Moinur Rahman test_work_dir_reuse()
123*6b13d60bSMuhammad Moinur Rahman {
124*6b13d60bSMuhammad Moinur Rahman 	// If kyua is built with debugging, it would abort here before the fix.
125*6b13d60bSMuhammad Moinur Rahman }
126*6b13d60bSMuhammad Moinur Rahman 
127*6b13d60bSMuhammad Moinur Rahman void
clean_up()128*6b13d60bSMuhammad Moinur Rahman clean_up()
129*6b13d60bSMuhammad Moinur Rahman {
130*6b13d60bSMuhammad Moinur Rahman 	(void)system("chflags -R nouunlink ../..");
131*6b13d60bSMuhammad Moinur Rahman }
132*6b13d60bSMuhammad Moinur Rahman 
133*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_0);
ATF_TEST_CASE_BODY(leak_0)134*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_0) { leak_work_dir(); }
135*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_1);
ATF_TEST_CASE_BODY(leak_1)136*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_1) { leak_work_dir(); }
137*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_2);
ATF_TEST_CASE_BODY(leak_2)138*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_2) { leak_work_dir(); }
139*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_3);
ATF_TEST_CASE_BODY(leak_3)140*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_3) { leak_work_dir(); }
141*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_4);
ATF_TEST_CASE_BODY(leak_4)142*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_4) { leak_work_dir(); }
143*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_5);
ATF_TEST_CASE_BODY(leak_5)144*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_5) { leak_work_dir(); }
145*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_6);
ATF_TEST_CASE_BODY(leak_6)146*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_6) { leak_work_dir(); }
147*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_7);
ATF_TEST_CASE_BODY(leak_7)148*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_7) { leak_work_dir(); }
149*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_8);
ATF_TEST_CASE_BODY(leak_8)150*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_8) { leak_work_dir(); }
151*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_9);
ATF_TEST_CASE_BODY(leak_9)152*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_9) { leak_work_dir(); }
153*6b13d60bSMuhammad Moinur Rahman 
154*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap);
ATF_TEST_CASE_BODY(pid_wrap)155*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap) { wrap_pids(); }
156*6b13d60bSMuhammad Moinur Rahman 
157*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_0);
ATF_TEST_CASE_BODY(pid_wrap_0)158*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_0) { test_work_dir_reuse(); }
159*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_1);
ATF_TEST_CASE_BODY(pid_wrap_1)160*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_1) { test_work_dir_reuse(); }
161*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_2);
ATF_TEST_CASE_BODY(pid_wrap_2)162*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_2) { test_work_dir_reuse(); }
163*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_3);
ATF_TEST_CASE_BODY(pid_wrap_3)164*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_3) { test_work_dir_reuse(); }
165*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_4);
ATF_TEST_CASE_BODY(pid_wrap_4)166*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_4) { test_work_dir_reuse(); }
167*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_5);
ATF_TEST_CASE_BODY(pid_wrap_5)168*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_5) { test_work_dir_reuse(); }
169*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_6);
ATF_TEST_CASE_BODY(pid_wrap_6)170*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_6) { test_work_dir_reuse(); }
171*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_7);
ATF_TEST_CASE_BODY(pid_wrap_7)172*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_7) { test_work_dir_reuse(); }
173*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_8);
ATF_TEST_CASE_BODY(pid_wrap_8)174*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_8) { test_work_dir_reuse(); }
175*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_9);
ATF_TEST_CASE_BODY(pid_wrap_9)176*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_9) { test_work_dir_reuse(); }
177*6b13d60bSMuhammad Moinur Rahman 
178*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(really_clean_up);
ATF_TEST_CASE_BODY(really_clean_up)179*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(really_clean_up) { clean_up(); }
180*6b13d60bSMuhammad Moinur Rahman 
ATF_INIT_TEST_CASES(tcs)181*6b13d60bSMuhammad Moinur Rahman ATF_INIT_TEST_CASES(tcs)
182*6b13d60bSMuhammad Moinur Rahman {
183*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_0);
184*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_1);
185*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_2);
186*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_3);
187*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_4);
188*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_5);
189*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_6);
190*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_7);
191*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_8);
192*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_9);
193*6b13d60bSMuhammad Moinur Rahman 
194*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap);
195*6b13d60bSMuhammad Moinur Rahman 
196*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_0);
197*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_1);
198*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_2);
199*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_3);
200*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_4);
201*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_5);
202*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_6);
203*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_7);
204*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_8);
205*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_9);
206*6b13d60bSMuhammad Moinur Rahman 
207*6b13d60bSMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, really_clean_up);
208*6b13d60bSMuhammad Moinur Rahman }
209