[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