[PATCH] D90201: Try reading a smaller chunk when (p)read fails

Jonas Devlieghere via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 26 17:28:25 PDT 2020


JDevlieghere created this revision.
JDevlieghere added reviewers: Bigcheese, arphaman, sylvestre.ledru, rnk, labath, thegameg.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.
JDevlieghere requested review of this revision.

Both `read` and `pread` can fail when trying to read chunks that are "too big", which to the best of my understanding is system dependent. When this happens, the call returns `-1` and sets `errno` to `EINVAL`.

I'm running into this when passing a 2.5G Mach-O to `llvm-dwarfdump`. Normally we would `mmap` the file, but this particular file happens to be the exact multiple of the page size (2628505600 bytes) in which case llvm prefers not to mmap (as to not waste a whole page for the terminating NULL byte).

This patch modifies `readNativeFileSlice` to try the syscall again with half the size of the requested buffer when the read fails with `EINVAL`.


https://reviews.llvm.org/D90201

Files:
  llvm/lib/Support/Unix/Path.inc


Index: llvm/lib/Support/Unix/Path.inc
===================================================================
--- llvm/lib/Support/Unix/Path.inc
+++ llvm/lib/Support/Unix/Path.inc
@@ -1075,15 +1075,18 @@
 
 Expected<size_t> readNativeFileSlice(file_t FD, MutableArrayRef<char> Buf,
                                      uint64_t Offset) {
+  auto Read = [&](size_t Size) {
 #ifdef HAVE_PREAD
-  ssize_t NumRead =
-      sys::RetryAfterSignal(-1, ::pread, FD, Buf.data(), Buf.size(), Offset);
+    return sys::RetryAfterSignal(-1, ::pread, FD, Buf.data(), Size, Offset);
 #else
-  if (lseek(FD, Offset, SEEK_SET) == -1)
-    return errorCodeToError(std::error_code(errno, std::generic_category()));
-  ssize_t NumRead =
-      sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Buf.size());
+    if (lseek(FD, Offset, SEEK_SET) == -1)
+      return -1;
+    return sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Size);
 #endif
+  };
+  ssize_t NumRead = Read(Buf.size());
+  if (NumRead == -1 && errno == EINVAL)
+    NumRead = Read(Buf.size() / 2); // Try reading a smaller chunk.
   if (NumRead == -1)
     return errorCodeToError(std::error_code(errno, std::generic_category()));
   return NumRead;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D90201.300834.patch
Type: text/x-patch
Size: 1199 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201027/cbe2b932/attachment.bin>


More information about the llvm-commits mailing list