Skip to content

Commit c28265d

Browse files
committed
test(process): reap signal helpers on failure
Guard the process-group helper and child immediately after fork so fatal test assertions cannot leave a paused helper or a gate-blocked child behind. Disarm each guard only after its normal waitpid succeeds, preserving the existing success path while keeping later dunitest cases isolated from failure-path processes. Signed-off-by: longjin <longjin@dragonos.org>
1 parent 4e99456 commit c28265d

1 file changed

Lines changed: 27 additions & 0 deletions

File tree

user/apps/tests/dunitest/suites/normal/process_signal_fork.cc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,29 @@ bool ReadInt(int fd, int* value) {
6666
return n == static_cast<ssize_t>(sizeof(*value));
6767
}
6868

69+
void KillAndReap(pid_t child) {
70+
if (child <= 0) {
71+
return;
72+
}
73+
kill(child, SIGKILL);
74+
while (waitpid(child, nullptr, 0) < 0 && errno == EINTR) {
75+
}
76+
}
77+
78+
class ChildProcessGuard {
79+
public:
80+
explicit ChildProcessGuard(pid_t child) : child_(child) {}
81+
ChildProcessGuard(const ChildProcessGuard&) = delete;
82+
ChildProcessGuard& operator=(const ChildProcessGuard&) = delete;
83+
84+
~ChildProcessGuard() { KillAndReap(child_); }
85+
86+
void Release() { child_ = -1; }
87+
88+
private:
89+
pid_t child_;
90+
};
91+
6992
void* PauseForeverThread(void*) {
7093
for (;;) {
7194
pause();
@@ -256,6 +279,7 @@ TEST(ProcessSignalFork, ThreadCreationPreservesInheritedGroupAndSingleDelivery)
256279
pause();
257280
}
258281
}
282+
ChildProcessGuard helper_guard(helper);
259283
ASSERT_TRUE(ReadByte(helper_ready[0])) << "helper did not become ready";
260284

261285
pid_t child = fork();
@@ -309,16 +333,19 @@ TEST(ProcessSignalFork, ThreadCreationPreservesInheritedGroupAndSingleDelivery)
309333
}
310334
_exit(0);
311335
}
336+
ChildProcessGuard child_guard(child);
312337

313338
ASSERT_EQ(0, setpgid(child, helper))
314339
<< "setpgid failed: errno=" << errno << " (" << strerror(errno) << ")";
315340
ASSERT_EQ(1, write(child_gate[1], "G", 1));
316341

317342
int status = 0;
318343
ASSERT_EQ(child, waitpid(child, &status, 0));
344+
child_guard.Release();
319345
ASSERT_EQ(0, kill(helper, SIGKILL));
320346
int helper_status = 0;
321347
ASSERT_EQ(helper, waitpid(helper, &helper_status, 0));
348+
helper_guard.Release();
322349
ASSERT_TRUE(WIFEXITED(status)) << "child status=" << status;
323350
EXPECT_EQ(0, WEXITSTATUS(status));
324351
}

0 commit comments

Comments
 (0)