[compiler-rt] [sanitizer] Large range support in IsAccessibleMemoryRange (PR #112665)
Florian Mayer via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 17 10:04:26 PDT 2024
================
@@ -288,26 +288,41 @@ bool SignalContext::IsStackOverflow() const {
#endif // SANITIZER_GO
+static void SetNonBlock(int fd) {
+ int res = fcntl(fd, F_GETFL, 0);
+ CHECK(!internal_iserror(res, nullptr));
+
+ res |= O_NONBLOCK;
+ res = fcntl(fd, F_SETFL, res);
+ CHECK(!internal_iserror(res, nullptr));
+}
+
bool IsAccessibleMemoryRange(uptr beg, uptr size) {
- uptr page_size = GetPageSizeCached();
- // Checking too large memory ranges is slow.
- CHECK_LT(size, page_size * 10);
- int sock_pair[2];
- if (pipe(sock_pair))
- return false;
- uptr bytes_written =
- internal_write(sock_pair[1], reinterpret_cast<void *>(beg), size);
- int write_errno;
- bool result;
- if (internal_iserror(bytes_written, &write_errno)) {
- CHECK_EQ(EFAULT, write_errno);
- result = false;
- } else {
- result = (bytes_written == size);
+ while (size) {
+ // `read` from `sock_pair[0]` into a dummy buffer to free up the pipe buffer
+ // for more `write` is slower than just recreating a pipe.
+ int sock_pair[2];
+ if (pipe(sock_pair))
+ return false;
+
+ auto cleanup = at_scope_exit([&]() {
+ internal_close(sock_pair[0]);
+ internal_close(sock_pair[1]);
+ });
+
+ SetNonBlock(sock_pair[1]);
+
+ int write_errno;
+ uptr w = internal_write(sock_pair[1], reinterpret_cast<char *>(beg), size);
+ if (internal_iserror(w, &write_errno)) {
+ CHECK_EQ(EFAULT, write_errno);
----------------
fmayer wrote:
We need to handle `EINTR` now or we could spuriously crash
https://github.com/llvm/llvm-project/pull/112665
More information about the llvm-commits
mailing list