Skip to content

Commit 718fbbe

Browse files
[llvm-exegesis] Kill process that recieve a signal (#86069)
Before this patch, llvm-exegesis would leave processes lingering that experienced signals like segmentation faults. They would up in a signal-delivery-stop state under the ptrace and never exit. This does not cause problems (or at least many) in llvm-exegesis as they are cleaned up after the main process exits, which usually happens quickly. However, in downstream use, when many blocks are being executed (many of which run into signals) within a single process, these processes stay around and can easily exhaust the process limit on some systems. This patch cleans them up by sending SIGKILL after information about the signal that was sent has been gathered.
1 parent 8d7d581 commit 718fbbe

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ class SubProcessFunctionExecutorImpl
342342
return make_error<Failure>("Failed to attach to the child process: " +
343343
Twine(strerror(errno)));
344344

345-
if (wait(NULL) == -1) {
345+
if (waitpid(ParentOrChildPID, NULL, 0) == -1) {
346346
return make_error<Failure>(
347347
"Failed to wait for child process to stop after attaching: " +
348348
Twine(strerror(errno)));
@@ -361,7 +361,7 @@ class SubProcessFunctionExecutorImpl
361361
return SendError;
362362

363363
int ChildStatus;
364-
if (wait(&ChildStatus) == -1) {
364+
if (waitpid(ParentOrChildPID, &ChildStatus, 0) == -1) {
365365
return make_error<Failure>(
366366
"Waiting for the child process to complete failed: " +
367367
Twine(strerror(errno)));
@@ -401,6 +401,20 @@ class SubProcessFunctionExecutorImpl
401401
Twine(strerror(errno)));
402402
}
403403

404+
// Send SIGKILL rather than SIGTERM as the child process has no SIGTERM
405+
// handlers to run, and calling SIGTERM would mean that ptrace will force
406+
// it to block in the signal-delivery-stop for the SIGSEGV/other signals,
407+
// and upon exit.
408+
if (kill(ParentOrChildPID, SIGKILL) == -1)
409+
return make_error<Failure>("Failed to kill child benchmarking proces: " +
410+
Twine(strerror(errno)));
411+
412+
// Wait for the process to exit so that there are no zombie processes left
413+
// around.
414+
if (waitpid(ParentOrChildPID, NULL, 0) == -1)
415+
return make_error<Failure>("Failed to wait for process to die: " +
416+
Twine(strerror(errno)));
417+
404418
if (ChildSignalInfo.si_signo == SIGSEGV)
405419
return make_error<SnippetSegmentationFault>(
406420
reinterpret_cast<intptr_t>(ChildSignalInfo.si_addr));

0 commit comments

Comments
 (0)