[libc-commits] [libc] [libc][test] Fix death test timeouts and dead-code elimination in math tests. (PR #227966)

via libc-commits libc-commits at lists.llvm.org
Wed Sep 30 23:04:42 PDT 2026


https://github.com/lntue created https://github.com/llvm/llvm-project/pull/227966

- In `ExecuteFunctionUnix.cpp`, call `prctl(PR_SET_DUMPABLE, 0)` in child processes to prevent external core dump handlers (such as apport) from intercepting expected crashes during death tests, eliminating 10s poll timeouts under parallel lit runs.
- Close `pipe_fds[0]` properly in `invoke_in_subprocess` to avoid leaking file descriptors.
- In math smoke test templates (`AddTest.h`, `SubTest.h`, `MulTest.h`, `DivTest.h`), assign test function results to `[[maybe_unused]] volatile OutType res` to prevent GCC from dead-code eliminating floating point operations in `test_inexact_results` when FMA optimization is disabled.

Assisted-by: Gemini

>From 617d21f8c3428e2794186a157319340bcea6d47b Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue at google.com>
Date: Thu, 1 Oct 2026 01:40:34 -0400
Subject: [PATCH 1/2] [libc][test] Fix death test timeouts and dead-code
 elimination in math tests.

- In `ExecuteFunctionUnix.cpp`, call `prctl(PR_SET_DUMPABLE, 0)` in child
  processes to prevent external core dump handlers (such as apport) from
  intercepting expected crashes during death tests, eliminating 10s poll
  timeouts under parallel lit runs.
- Close `pipe_fds[0]` properly in `invoke_in_subprocess` to avoid leaking
  file descriptors.
- In math smoke test templates (`AddTest.h`, `SubTest.h`, `MulTest.h`,
  `DivTest.h`), assign test function results to `[[maybe_unused]] volatile OutType res`
  to prevent GCC from dead-code eliminating floating point operations in
  `test_inexact_results` when FMA optimization is disabled.

Assisted-by: Gemini
---
 libc/test/UnitTest/ExecuteFunctionUnix.cpp | 10 ++++++++++
 libc/test/src/math/smoke/AddTest.h         |  2 +-
 libc/test/src/math/smoke/DivTest.h         |  2 +-
 libc/test/src/math/smoke/MulTest.h         |  2 +-
 libc/test/src/math/smoke/SubTest.h         |  2 +-
 5 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/libc/test/UnitTest/ExecuteFunctionUnix.cpp b/libc/test/UnitTest/ExecuteFunctionUnix.cpp
index a07c92f61225c..1f335473ebf8b 100644
--- a/libc/test/UnitTest/ExecuteFunctionUnix.cpp
+++ b/libc/test/UnitTest/ExecuteFunctionUnix.cpp
@@ -38,6 +38,9 @@
 #include <string.h>
 #include <sys/wait.h>
 #include <unistd.h>
+#ifdef __linux__
+#include <sys/prctl.h>
+#endif
 
 #define LIBC_IMPL
 #endif
@@ -75,6 +78,10 @@ ProcessStatus invoke_in_subprocess(FunctionCaller *func, int timeout_ms) {
   }
 
   if (!pid) {
+    LIBC_IMPL::close(pipe_fds[0]);
+#if defined(__linux__) && defined(PR_SET_DUMPABLE)
+    ::prctl(PR_SET_DUMPABLE, 0);
+#endif
     (*func)();
     delete func;
     LIBC_IMPL::exit(0);
@@ -85,15 +92,18 @@ ProcessStatus invoke_in_subprocess(FunctionCaller *func, int timeout_ms) {
   // No events requested so this call will only return after the timeout or if
   // the pipes peer was closed, signaling the process exited.
   if (LIBC_IMPL::poll(&poll_fd, 1, timeout_ms) == -1) {
+    LIBC_IMPL::close(pipe_fds[0]);
     delete func;
     return ProcessStatus::error("poll(2) failed");
   }
   // If the pipe wasn't closed by the child yet then timeout has expired.
   if (!(poll_fd.revents & POLLHUP)) {
+    LIBC_IMPL::close(pipe_fds[0]);
     LIBC_IMPL::kill(pid, SIGKILL);
     delete func;
     return ProcessStatus::timed_out_ps();
   }
+  LIBC_IMPL::close(pipe_fds[0]);
 
   int wstatus = 0;
   // Wait on the pid of the subprocess here so it gets collected by the system
diff --git a/libc/test/src/math/smoke/AddTest.h b/libc/test/src/math/smoke/AddTest.h
index 99cb025538f7d..8b2a241a9596e 100644
--- a/libc/test/src/math/smoke/AddTest.h
+++ b/libc/test/src/math/smoke/AddTest.h
@@ -135,7 +135,7 @@ class AddTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
   }
 
   void test_inexact_results(AddFunc func) {
-    func(InType(1.0), in.min_denormal);
+    [[maybe_unused]] volatile OutType res = func(InType(1.0), in.min_denormal);
     EXPECT_FP_EXCEPTION(FE_INEXACT);
   }
 
diff --git a/libc/test/src/math/smoke/DivTest.h b/libc/test/src/math/smoke/DivTest.h
index ebce775d9eabd..b1303bf2815fb 100644
--- a/libc/test/src/math/smoke/DivTest.h
+++ b/libc/test/src/math/smoke/DivTest.h
@@ -147,7 +147,7 @@ class DivTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
   }
 
   void test_inexact_results(DivFunc func) {
-    func(InType(1.0), InType(3.0));
+    [[maybe_unused]] volatile OutType res = func(InType(1.0), InType(3.0));
     EXPECT_FP_EXCEPTION(FE_INEXACT);
   }
 };
diff --git a/libc/test/src/math/smoke/MulTest.h b/libc/test/src/math/smoke/MulTest.h
index c9327b3c6e285..25a0949147a8c 100644
--- a/libc/test/src/math/smoke/MulTest.h
+++ b/libc/test/src/math/smoke/MulTest.h
@@ -137,7 +137,7 @@ class MulTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     InFPBits x_bits = InFPBits::one();
     x_bits.set_mantissa(InFPBits::SIG_MASK);
     InType x = x_bits.get_val();
-    func(x, x);
+    [[maybe_unused]] volatile OutType res = func(x, x);
     EXPECT_FP_EXCEPTION(FE_INEXACT);
   }
 };
diff --git a/libc/test/src/math/smoke/SubTest.h b/libc/test/src/math/smoke/SubTest.h
index b1ead64e71f1c..72f596d13381e 100644
--- a/libc/test/src/math/smoke/SubTest.h
+++ b/libc/test/src/math/smoke/SubTest.h
@@ -131,7 +131,7 @@ class SubTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
   }
 
   void test_inexact_results(SubFunc func) {
-    func(InType(1.0), in.min_denormal);
+    [[maybe_unused]] volatile OutType res = func(InType(1.0), in.min_denormal);
     EXPECT_FP_EXCEPTION(FE_INEXACT);
   }
 

>From 4a48eb9276f56a92a66c60c7ff3beab6cb3dce26 Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue at google.com>
Date: Thu, 1 Oct 2026 02:03:16 -0400
Subject: [PATCH 2/2] [libc][test] Use LIBC_IMPL::prctl and add prctl
 dependency in full build.

- In `ExecuteFunctionUnix.cpp`, use `LIBC_IMPL::prctl` instead of `::prctl`
  and include `<linux/prctl.h>` / `"src/sys/prctl/prctl.h"` in full build mode.
- In `libc/test/UnitTest/CMakeLists.txt`, add `libc.src.sys.prctl.prctl` to
  `libc_death_test_deps` when targeting Linux in full build mode.

Assisted-by: Gemini
---
 libc/test/UnitTest/CMakeLists.txt          | 5 +++++
 libc/test/UnitTest/ExecuteFunctionUnix.cpp | 6 +++++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/libc/test/UnitTest/CMakeLists.txt b/libc/test/UnitTest/CMakeLists.txt
index 99350d4415b39..1dd3f411f5842 100644
--- a/libc/test/UnitTest/CMakeLists.txt
+++ b/libc/test/UnitTest/CMakeLists.txt
@@ -142,6 +142,11 @@ if(LIBC_TEST_SUBPROCESS_TESTS)
       libc.include.llvm-libc-types.pid_t
       libc.include.llvm-libc-types.struct_pollfd
     )
+    if(TARGET libc.src.sys.prctl.prctl)
+      list(APPEND libc_death_test_deps
+        libc.src.sys.prctl.prctl
+      )
+    endif()
   endif()
   add_unittest_framework_library(
     LibcDeathTestExecutors
diff --git a/libc/test/UnitTest/ExecuteFunctionUnix.cpp b/libc/test/UnitTest/ExecuteFunctionUnix.cpp
index 1f335473ebf8b..0bc16ab672f14 100644
--- a/libc/test/UnitTest/ExecuteFunctionUnix.cpp
+++ b/libc/test/UnitTest/ExecuteFunctionUnix.cpp
@@ -27,6 +27,10 @@
 #include "src/unistd/close.h"
 #include "src/unistd/fork.h"
 #include "src/unistd/pipe.h"
+#ifdef __linux__
+#include <linux/prctl.h>
+#include "src/sys/prctl/prctl.h"
+#endif
 
 #define LIBC_IMPL LIBC_NAMESPACE
 
@@ -80,7 +84,7 @@ ProcessStatus invoke_in_subprocess(FunctionCaller *func, int timeout_ms) {
   if (!pid) {
     LIBC_IMPL::close(pipe_fds[0]);
 #if defined(__linux__) && defined(PR_SET_DUMPABLE)
-    ::prctl(PR_SET_DUMPABLE, 0);
+    LIBC_IMPL::prctl(PR_SET_DUMPABLE, 0);
 #endif
     (*func)();
     delete func;



More information about the libc-commits mailing list