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