Skip to content

Commit ea762a7

Browse files
committed
Ensure we handle EINTR & partial operations more consistently for pwrite
1 parent 8987634 commit ea762a7

File tree

2 files changed

+79
-14
lines changed

2 files changed

+79
-14
lines changed

src/coreclr/debug/createdump/crashinfounix.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ CrashInfo::ReadProcessMemory(uint64_t address, void* buffer, size_t size, size_t
543543
// performance optimization.
544544
m_canUseProcVmReadSyscall = false;
545545
assert(m_fdMem != -1);
546-
*read = pread(m_fdMem, buffer, size, (off_t)address);
546+
while (-1 == (ssize_t)(*read = pread(m_fdMem, buffer, size, (off_t)address)) && errno == EINTR);
547547
}
548548

549549
if (*read == (size_t)-1)

src/coreclr/pal/src/map/map.cpp

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1968,9 +1968,36 @@ MAPmmapAndRecord(
19681968
// Set the requested mapping with forced PROT_WRITE to ensure data from the file can be read there,
19691969
// read the data in and finally remove the forced PROT_WRITE. On Intel we can still switch the
19701970
// protection later with mprotect.
1971-
if ((mprotect(pvBaseAddress, len + adjust, PROT_WRITE) == -1) ||
1972-
(pread(fd, pvBaseAddress, len + adjust, offset - adjust) == -1) ||
1973-
(mprotect(pvBaseAddress, len + adjust, prot) == -1))
1971+
bool failCondition = mprotect(pvBaseAddress, len + adjust, PROT_WRITE) == -1;
1972+
if (!failCondition)
1973+
{
1974+
unsigned char* buf = pvBaseAddress;
1975+
size_t nbyte = len + adjust;
1976+
size_t offset2 = offset - adjust;
1977+
while (nbyte > 0)
1978+
{
1979+
ssize_t result;
1980+
while (-1 == result = pread(fd, buf, nbyte, offset2) && errno == EINTR);
1981+
if (result == -1)
1982+
{
1983+
failCondition = true;
1984+
break;
1985+
}
1986+
buf += result;
1987+
nbyte -= result;
1988+
offset2 += result;
1989+
if (result == 0)
1990+
{
1991+
if (nbyte > 0)
1992+
{
1993+
failCondition = true;
1994+
errno = EIO; // set to a generic IO error, to indicate that we couldn't read the whole requested region
1995+
}
1996+
break;
1997+
}
1998+
}
1999+
}
2000+
if (failCondition || (mprotect(pvBaseAddress, len + adjust, prot) == -1))
19742001
{
19752002
palError = FILEGetLastErrorFromErrno();
19762003
}
@@ -2080,16 +2107,54 @@ void * MAPMapPEFile(HANDLE hFile, off_t offset)
20802107
//Step 1: Read the PE headers and reserve enough space for the whole image somewhere.
20812108
IMAGE_DOS_HEADER dosHeader;
20822109
IMAGE_NT_HEADERS ntHeader;
2083-
if (sizeof(dosHeader) != pread(fd, &dosHeader, sizeof(dosHeader), offset))
2084-
{
2085-
palError = FILEGetLastErrorFromErrno();
2086-
ERROR_(LOADER)( "reading dos header failed\n" );
2087-
goto done;
2088-
}
2089-
if (sizeof(ntHeader) != pread(fd, &ntHeader, sizeof(ntHeader), offset + dosHeader.e_lfanew))
2090-
{
2091-
palError = FILEGetLastErrorFromErrno();
2092-
goto done;
2110+
unsigned char* preadBuf = &dosHeader;
2111+
size_t nbyte = sizeof(dosHeader);
2112+
size_t preadOffset = offset;
2113+
while (nbyte > 0)
2114+
{
2115+
ssize_t result;
2116+
while (-1 == result = pread(fd, preadBuf, nbyte, preadOffset) && errno == EINTR);
2117+
if (result == 0)
2118+
{
2119+
if (nbyte > 0)
2120+
{
2121+
errno = EIO; // set to a generic IO error, to indicate that we couldn't read the whole requested region
2122+
result = -1;
2123+
}
2124+
}
2125+
if (result == -1)
2126+
{
2127+
palError = FILEGetLastErrorFromErrno();
2128+
ERROR_(LOADER)( "reading dos header failed\n" );
2129+
goto done;
2130+
}
2131+
preadBuf += result;
2132+
nbyte -= result;
2133+
preadOffset += result;
2134+
}
2135+
unsigned char* preadBuf = &ntHeader;
2136+
size_t nbyte = sizeof(ntHeader);
2137+
size_t preadOffset = offset + dosHeader.e_lfanew;
2138+
while (nbyte > 0)
2139+
{
2140+
ssize_t result;
2141+
while (-1 == result = pread(fd, preadBuf, nbyte, preadOffset) && errno == EINTR);
2142+
if (result == 0)
2143+
{
2144+
if (nbyte > 0)
2145+
{
2146+
errno = EIO; // set to a generic IO error, to indicate that we couldn't read the whole requested region
2147+
result = -1;
2148+
}
2149+
}
2150+
if (result == -1)
2151+
{
2152+
palError = FILEGetLastErrorFromErrno();
2153+
goto done;
2154+
}
2155+
preadBuf += result;
2156+
nbyte -= result;
2157+
preadOffset += result;
20932158
}
20942159

20952160
if ((VAL16(IMAGE_DOS_SIGNATURE) != VAL16(dosHeader.e_magic))

0 commit comments

Comments
 (0)