Skip to content

Commit bdc0119

Browse files
authored
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.
1 parent b44c50d commit bdc0119

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

llvm/lib/Support/ErrorHandling.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS
2020
#include "llvm/Support/Debug.h"
2121
#include "llvm/Support/Errc.h"
22+
#include "llvm/Support/Errno.h"
2223
#include "llvm/Support/Error.h"
2324
#include "llvm/Support/Process.h"
2425
#include "llvm/Support/Signals.h"
@@ -62,6 +63,17 @@ static std::mutex ErrorHandlerMutex;
6263
static std::mutex BadAllocErrorHandlerMutex;
6364
#endif
6465

66+
static bool write_retry(int fd, const char *buf, size_t count) {
67+
while (count > 0) {
68+
ssize_t written = sys::RetryAfterSignal(-1, ::write, fd, buf, count);
69+
if (written <= 0)
70+
return false;
71+
buf += written;
72+
count -= written;
73+
}
74+
return true;
75+
}
76+
6577
void llvm::install_fatal_error_handler(fatal_error_handler_t handler,
6678
void *user_data) {
6779
#if LLVM_ENABLE_THREADS == 1
@@ -111,8 +123,7 @@ void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) {
111123
raw_svector_ostream OS(Buffer);
112124
OS << "LLVM ERROR: " << Reason << "\n";
113125
StringRef MessageStr = OS.str();
114-
ssize_t written = ::write(2, MessageStr.data(), MessageStr.size());
115-
(void)written; // If something went wrong, we deliberately just give up.
126+
write_retry(2, MessageStr.data(), MessageStr.size());
116127
}
117128

118129
// 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) {
190201
// an OOM to stderr and abort.
191202
const char *OOMMessage = "LLVM ERROR: out of memory\n";
192203
const char *Newline = "\n";
193-
(void)!::write(2, OOMMessage, strlen(OOMMessage));
194-
(void)!::write(2, Reason, strlen(Reason));
195-
(void)!::write(2, Newline, strlen(Newline));
204+
write_retry(2, OOMMessage, strlen(OOMMessage));
205+
write_retry(2, Reason, strlen(Reason));
206+
write_retry(2, Newline, strlen(Newline));
196207
abort();
197208
#endif
198209
}

0 commit comments

Comments
 (0)