[compiler-rt] compiler-rt: sanitizer_common: use close_range() instead of looping (PR #114442)

Kyle Evans via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 31 11:16:27 PDT 2024


https://github.com/kevans91 created https://github.com/llvm/llvm-project/pull/114442

_SC_OPEN_MAX is quite high on FreeBSD, which makes this close() loop a quite obvious problem when attempting to do any kind of debugging in a process that uses StartSubprocess.  Switch to using close_range(2) instead to close them all in a single syscall and dramatically reduce the runtime and syscall trace noise

Linux has an equivalent syscall, but I do not have the capacity to test that it works there, so this is limited to SANITIZER_FREEBSD for the time being.

>From f942908ddf04f046f4fbf2644c5a5b791232da6a Mon Sep 17 00:00:00 2001
From: Kyle Evans <kevans at FreeBSD.org>
Date: Thu, 31 Oct 2024 13:06:40 -0500
Subject: [PATCH] compiler-rt: sanitizer_common: use close_range() instead of
 looping

_SC_OPEN_MAX is quite high on FreeBSD, which makes this close() loop a quite
obvious problem when attempting to do any kind of debugging in a process
that uses StartSubprocess.  Switch to using close_range(2) instead to close
them all in a single syscall and dramatically reduce the runtime and syscall
trace noise

Linux has an equivalent syscall, but I do not have the capacity to test that
it works there, so this is limited to SANITIZER_FREEBSD for the time being.
---
 compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp         | 5 +++++
 compiler-rt/lib/sanitizer_common/sanitizer_posix.h           | 3 +++
 compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp | 4 ++++
 3 files changed, 12 insertions(+)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
index 33107eb0b42993..8b1850f85010cf 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
@@ -256,6 +256,11 @@ int internal_madvise(uptr addr, uptr length, int advice) {
   return internal_syscall(SYSCALL(madvise), addr, length, advice);
 }
 
+#    if SANITIZER_FREEBSD
+uptr internal_close_range(fd_t lowfd, fd_t highfd, int flags) {
+  return internal_syscall(SYSCALL(close_range), lowfd, highfd, flags);
+}
+#    endif
 uptr internal_close(fd_t fd) { return internal_syscall(SYSCALL(close), fd); }
 
 uptr internal_open(const char *filename, int flags) {
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h
index 1f0795caa420c7..b5491c540dc083 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h
@@ -28,6 +28,9 @@ namespace __sanitizer {
 // Don't use directly, use __sanitizer::OpenFile() instead.
 uptr internal_open(const char *filename, int flags);
 uptr internal_open(const char *filename, int flags, u32 mode);
+#  if SANITIZER_FREEBSD
+uptr internal_close_range(fd_t lowfd, fd_t highfd, int flags);
+#  endif
 uptr internal_close(fd_t fd);
 
 uptr internal_read(fd_t fd, void *buf, uptr count);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
index 7ee2319456d23e..894998090b01b3 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
@@ -543,7 +543,11 @@ pid_t StartSubprocess(const char *program, const char *const argv[],
       internal_close(stderr_fd);
     }
 
+#  if SANITIZER_FREEBSD
+    internal_close_range(3, ~0U, 0);
+#  else
     for (int fd = sysconf(_SC_OPEN_MAX); fd > 2; fd--) internal_close(fd);
+#  endif
 
     internal_execve(program, const_cast<char **>(&argv[0]),
                     const_cast<char *const *>(envp));



More information about the llvm-commits mailing list