[llvm] bdc0119 - ErrorHandling: Check for EINTR and partial writes (#147595)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 9 11:19:24 PDT 2025


Author: Matthias Braun
Date: 2025-07-09T11:19:21-07:00
New Revision: bdc0119e1b6001be813a540134bd1772b4d9c4dc

URL: https://github.com/llvm/llvm-project/commit/bdc0119e1b6001be813a540134bd1772b4d9c4dc
DIFF: https://github.com/llvm/llvm-project/commit/bdc0119e1b6001be813a540134bd1772b4d9c4dc.diff

LOG: ErrorHandling: Check for EINTR and partial writes (#147595)

Calls to the posix `write` function can return -1 and set errno to
`EINTR` or perform partial writes when interrupted by signals. In those
cases applications are supposed to just try again. See for example the
documentation in glibc:
https://sourceware.org/glibc/manual/latest/html_node/I_002fO-Primitives.html#index-write

This fixes the uses in `ErrorHandling.cpp` to retry as needed.

Added: 
    

Modified: 
    llvm/lib/Support/ErrorHandling.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
index cc16f2037ea58..097041f1ae282 100644
--- a/llvm/lib/Support/ErrorHandling.cpp
+++ b/llvm/lib/Support/ErrorHandling.cpp
@@ -19,6 +19,7 @@
 #include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Errc.h"
+#include "llvm/Support/Errno.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/Process.h"
 #include "llvm/Support/Signals.h"
@@ -62,6 +63,17 @@ static std::mutex ErrorHandlerMutex;
 static std::mutex BadAllocErrorHandlerMutex;
 #endif
 
+static bool write_retry(int fd, const char *buf, size_t count) {
+  while (count > 0) {
+    ssize_t written = sys::RetryAfterSignal(-1, ::write, fd, buf, count);
+    if (written <= 0)
+      return false;
+    buf += written;
+    count -= written;
+  }
+  return true;
+}
+
 void llvm::install_fatal_error_handler(fatal_error_handler_t handler,
                                        void *user_data) {
 #if LLVM_ENABLE_THREADS == 1
@@ -111,8 +123,7 @@ void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) {
     raw_svector_ostream OS(Buffer);
     OS << "LLVM ERROR: " << Reason << "\n";
     StringRef MessageStr = OS.str();
-    ssize_t written = ::write(2, MessageStr.data(), MessageStr.size());
-    (void)written; // If something went wrong, we deliberately just give up.
+    write_retry(2, MessageStr.data(), MessageStr.size());
   }
 
   // If we reached here, we are failing ungracefully. Run the interrupt handlers
@@ -190,9 +201,9 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) {
   // an OOM to stderr and abort.
   const char *OOMMessage = "LLVM ERROR: out of memory\n";
   const char *Newline = "\n";
-  (void)!::write(2, OOMMessage, strlen(OOMMessage));
-  (void)!::write(2, Reason, strlen(Reason));
-  (void)!::write(2, Newline, strlen(Newline));
+  write_retry(2, OOMMessage, strlen(OOMMessage));
+  write_retry(2, Reason, strlen(Reason));
+  write_retry(2, Newline, strlen(Newline));
   abort();
 #endif
 }


        


More information about the llvm-commits mailing list