Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
4fa0d88
Fix handling of `readdir` giving `EINTR`
hamarb123 Jul 7, 2025
0049bf3
Fix handling of `opendir` giving `EINTR`
hamarb123 Jul 7, 2025
a9793f8
Ensure handling of `fcntl` giving `EINTR` is consistent
hamarb123 Jul 7, 2025
ec72822
Ensure handling of `fsync` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
7e0a56d
Ensure handling of `chmod` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
d6a331a
Ensure handling of `ftruncate` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
aa891dd
Ensure handling of `flock` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
b159416
Ensure handling of `poll` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
143b964
Ensure handling of `waitpid` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
42f82c9
Ensure handling of `getpwuid` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
7516565
Ensure handling of `recvmsg` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
73d7e28
Ensure handling of `stat` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
7e013bf
Ensure handling of variants of `stat` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
085fd17
Ensure handling of `unlink` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
9776101
Ensure handling of `shm_unlink` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
651d928
Ensure handling of `pipe{2}` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
f4cb957
Ensure handling of `mkdir` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
1465bf9
Ensure handling of `chdir` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
f671ff1
Ensure handling of `mkfifo` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
e01584a
Ensure handling of `rename` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
33759b6
Ensure handling of `rmdir` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
ddec1a9
Ensure handling of `ioctl` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
8779bb6
Ensure handling of all variants of `statfs` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
36f241d
Ensure handling of `sendmsg` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
dfd3972
Ensure handling of `accept` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
a395f6e
Ensure handling of `connect` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
c791791
Ensure handling of `kevent` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
aa5f35c
Ensure handling of `dup2` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
400e7f6
Ensure handling of `remove` giving `EINTR` is consistent
hamarb123 Jul 8, 2025
d5024c5
Ensure handling of `lseek` & variants giving `EINTR` is consistent
hamarb123 Jul 18, 2025
143d9ce
Ensure handling of `open` & variants giving `EINTR` is consistent
hamarb123 Jul 18, 2025
3aa031f
Ensure we handle `EINTR` & partial operations more consistently for `…
hamarb123 Jul 30, 2025
8987634
Fix handling of `closedir` giving `EINTR`
hamarb123 Jul 30, 2025
e99a739
Ensure we handle EINTR & partial operations more consistently for pread
hamarb123 Oct 2, 2025
ae26757
Ensure we handle EINTR & partial operations more consistently for read
hamarb123 Oct 2, 2025
b6f7090
Merge remote-tracking branch 'upstream/main' into main28
hamarb123 Oct 3, 2025
6752334
Fix first set of build failures
hamarb123 Oct 3, 2025
23b6275
Fix build failures
hamarb123 Oct 3, 2025
70051f4
Fix build failures
hamarb123 Oct 3, 2025
ffc73d2
Fix build failures
hamarb123 Oct 3, 2025
67adb47
Fix build failures
hamarb123 Oct 3, 2025
85267d7
Merge remote-tracking branch 'upstream/main' into main28
hamarb123 Oct 7, 2025
8f0530e
Fix build errors
hamarb123 Oct 7, 2025
fa92a01
Merge branch 'main' into main28
hamarb123 Oct 7, 2025
7a0a208
Fix build error
hamarb123 Oct 7, 2025
7185b99
Fix compiler error
hamarb123 Oct 7, 2025
3f850e7
typo
hamarb123 Oct 7, 2025
7018912
Fix build errors
hamarb123 Oct 7, 2025
b2952f5
Remove unrelated whitespace changes VSC added
hamarb123 Oct 7, 2025
9d34503
Fix compile error
hamarb123 Oct 7, 2025
a130b68
Remove unrelated whitespace changes VSC added
hamarb123 Oct 7, 2025
80e4581
Fix compile error
hamarb123 Oct 7, 2025
0cb50d0
Merge branch 'main' into main28
hamarb123 Oct 7, 2025
f83da62
Fix compile error
hamarb123 Oct 7, 2025
42b7dbf
Merge branch 'main' into main28
hamarb123 Nov 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions src/coreclr/debug/createdump/crashinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -814,20 +814,32 @@ CrashInfo::PageMappedToPhysicalMemory(uint64_t start)
}

uint64_t pagemapOffset = (start / PAGE_SIZE) * sizeof(uint64_t);
uint64_t seekResult = lseek(m_fdPagemap, (off_t) pagemapOffset, SEEK_SET);
if (seekResult != pagemapOffset)
int64_t seekResult;
while (-1 == (seekResult = lseek(m_fdPagemap, (off_t) pagemapOffset, SEEK_SET)) && errno == EINTR);
if ((uint64_t)seekResult != pagemapOffset)
{
int seekErrno = errno;
TRACE("Seeking in pagemap file FAILED, addr: %" PRIA PRIx ", pagemap offset: %" PRIA PRIx ", ERRNO %d: %s\n", start, pagemapOffset, seekErrno, strerror(seekErrno));
return true;
}
uint64_t value;
size_t readResult = read(m_fdPagemap, (void*)&value, sizeof(value));
if (readResult == (size_t) -1)
size_t readSoFar = 0;
while (readSoFar < sizeof(value))
{
int readErrno = errno;
TRACE("Reading of pagemap file FAILED, addr: %" PRIA PRIx ", pagemap offset: %" PRIA PRIx ", size: %zu, ERRNO %d: %s\n", start, pagemapOffset, sizeof(value), readErrno, strerror(readErrno));
return true;
ssize_t readResult;
while (-1 == (readResult = read(m_fdPagemap, (unsigned char*)&value + readSoFar, sizeof(value) - readSoFar) && errno == EINTR));
if (readResult == -1)
{
int readErrno = errno;
TRACE("Reading of pagemap file FAILED, addr: %" PRIA PRIx ", pagemap offset: %" PRIA PRIx ", size: %zu, ERRNO %d: %s\n", start, pagemapOffset, sizeof(value), readErrno, strerror(readErrno));
return true;
}
if (readResult == 0)
{
TRACE("Reading of pagemap file FAILED, addr: %" PRIA PRIx ", pagemap offset: %" PRIA PRIx ", size: %zu, Read Was Incomplete\n", start, pagemapOffset, sizeof(value));
return true;
}
readSoFar += (size_t)readResult;
}

bool is_page_present = (value & ((uint64_t)1 << 63)) != 0;
Expand Down
45 changes: 36 additions & 9 deletions src/coreclr/debug/createdump/crashinfounix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ CrashInfo::Initialize()
return false;
}

m_fdMem = open(memPath, O_RDONLY);
while (-1 == (m_fdMem = open(memPath, O_RDONLY)) && errno == EINTR);
if (m_fdMem == -1)
{
int err = errno;
Expand Down Expand Up @@ -54,7 +54,7 @@ CrashInfo::Initialize()
printf_error("snprintf failed building /proc/<pid>/pagemap name\n");
return false;
}
m_fdPagemap = open(pagemapPath, O_RDONLY);
while (-1 == (m_fdPagemap = open(pagemapPath, O_RDONLY)) && errno == EINTR);
if (m_fdPagemap == -1)
{
TRACE("open(%s) FAILED %d (%s), will fallback to dumping all memory regions without checking if they are committed\n", pagemapPath, errno, strerror(errno));
Expand Down Expand Up @@ -84,7 +84,7 @@ CrashInfo::CleanupAndResumeProcess()
if (ptrace(PTRACE_DETACH, thread->Tid(), nullptr, nullptr) != -1)
{
int waitStatus;
waitpid(thread->Tid(), &waitStatus, __WALL);
while (-1 == waitpid(thread->Tid(), &waitStatus, __WALL) && errno == EINTR);
}
}
if (m_fdMem != -1)
Expand Down Expand Up @@ -113,24 +113,34 @@ CrashInfo::EnumerateAndSuspendThreads()
return false;
}

DIR* taskDir = opendir(taskPath);
DIR* taskDir;
while ((taskDir = opendir(taskPath)) == nullptr && errno == EINTR);

if (taskDir == nullptr)
{
printf_error("Problem enumerating threads: opendir(%s) FAILED %s (%d)\n", taskPath, strerror(errno), errno);
return false;
}

struct dirent* entry;
while ((entry = readdir(taskDir)) != nullptr)
while (true)
{
do
{
errno = 0;
entry = readdir(taskDir);
}
while (entry == nullptr && errno == EINTR);
if (entry == nullptr) break;

pid_t tid = static_cast<pid_t>(strtol(entry->d_name, nullptr, 10));
if (tid != 0)
{
// Reference: http://stackoverflow.com/questions/18577956/how-to-use-ptrace-to-get-a-consistent-view-of-multiple-threads
if (ptrace(PTRACE_ATTACH, tid, nullptr, nullptr) != -1)
{
int waitStatus;
waitpid(tid, &waitStatus, __WALL);
while (-1 == waitpid(tid, &waitStatus, __WALL) && errno == EINTR);
}
else
{
Expand Down Expand Up @@ -166,7 +176,8 @@ CrashInfo::GetAuxvEntries()
printf_error("snprintf failed building /proc/<pid>/auxv\n");
return false;
}
int fd = open(auxvPath, O_RDONLY, 0);
int fd;
while (-1 == (fd = open(auxvPath, O_RDONLY, 0)) && errno == EINTR);
if (fd == -1)
{
printf_error("Problem reading aux info: open(%s) FAILED %s (%d)\n", auxvPath, strerror(errno), errno);
Expand All @@ -175,8 +186,24 @@ CrashInfo::GetAuxvEntries()
bool result = false;
elf_aux_entry auxvEntry;

while (read(fd, &auxvEntry, sizeof(elf_aux_entry)) == sizeof(elf_aux_entry))
while (true)
{
size_t readSoFar = 0;
while (readSoFar < sizeof(elf_aux_entry))
{
ssize_t readResult;
while (-1 == (readResult = read(fd, (unsigned char*)&auxvEntry + readSoFar, sizeof(elf_aux_entry) - readSoFar) && errno == EINTR));
if (readResult == -1)
{
break;
}
if (readResult == 0)
{
break;
}
readSoFar += (size_t)readResult;
}
if (readSoFar != sizeof(elf_aux_entry)) break;
m_auxvEntries.push_back(auxvEntry);
if (auxvEntry.a_type == AT_NULL)
{
Expand Down Expand Up @@ -532,7 +559,7 @@ CrashInfo::ReadProcessMemory(uint64_t address, void* buffer, size_t size, size_t
// performance optimization.
m_canUseProcVmReadSyscall = false;
assert(m_fdMem != -1);
*read = pread(m_fdMem, buffer, size, (off_t)address);
while (-1 == (ssize_t)(*read = pread(m_fdMem, buffer, size, (off_t)address)) && errno == EINTR);
}

if (*read == (size_t)-1)
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/debug/createdump/crashreportwriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ CrashReportWriter::WriteCrashReport(const std::string& dumpFileName)
printf_error("Writing the crash report file FAILED\n");

// Delete the partial json file on error
remove(crashReportFile.c_str());
while (-1 == remove(crashReportFile.c_str()) && errno == EINTR);
}
}

Expand Down Expand Up @@ -270,7 +270,7 @@ CrashReportWriter::WriteStackFrame(const StackFrame& frame)
bool
CrashReportWriter::OpenWriter(const char* fileName)
{
m_fd = open(fileName, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR | S_IRUSR);
while (-1 == (m_fd = open(fileName, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR | S_IRUSR)) && errno == EINTR);
if (m_fd == -1)
{
printf_error("Could not create json file '%s': %s (%d)\n", fileName, strerror(errno), errno);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/debug/createdump/createdumpunix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ CreateDump(const CreateDumpOptions& options)
printf_error("Writing dump FAILED\n");

// Delete the partial dump file on error
remove(dumpPath.c_str());
while (-1 == remove(dumpPath.c_str()) && errno == EINTR);
goto exit;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/debug/createdump/dumpwriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ DumpWriter::~DumpWriter()
bool
DumpWriter::OpenDump(const char* dumpFileName)
{
m_fd = open(dumpFileName, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR | S_IRUSR);
while (-1 == (m_fd = open(dumpFileName, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR | S_IRUSR)) && errno == EINTR);
if (m_fd == -1)
{
printf_error("Could not create output file '%s': %s (%d)\n", dumpFileName, strerror(errno), errno);
Expand Down
38 changes: 23 additions & 15 deletions src/coreclr/debug/debug-pal/unix/twowaypipe.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#include <errno.h>
#include <pal.h>
#include <unistd.h>
#include <fcntl.h>
Expand All @@ -22,19 +23,22 @@ bool TwoWayPipe::CreateServer(const ProcessDescriptor& pd)
PAL_GetTransportPipeName(m_inPipeName, pd.m_Pid, pd.m_ApplicationGroupId, "in");
PAL_GetTransportPipeName(m_outPipeName, pd.m_Pid, pd.m_ApplicationGroupId, "out");

unlink(m_inPipeName);
while (-1 == unlink(m_inPipeName) && errno == EINTR);

if (mkfifo(m_inPipeName, S_IRWXU) == -1)
int mkfifo_result;
while (-1 == (mkfifo_result = mkfifo(m_inPipeName, S_IRWXU)) && errno == EINTR);
if (mkfifo_result == -1)
{
return false;
}


unlink(m_outPipeName);
while (-1 == unlink(m_outPipeName) && errno == EINTR);

if (mkfifo(m_outPipeName, S_IRWXU) == -1)
while (-1 == (mkfifo_result = mkfifo(m_outPipeName, S_IRWXU)) && errno == EINTR);
if (mkfifo_result == -1)
{
unlink(m_inPipeName);
while (-1 == unlink(m_inPipeName) && errno == EINTR);
return false;
}

Expand All @@ -57,13 +61,13 @@ bool TwoWayPipe::Connect(const ProcessDescriptor& pd)

// Pipe opening order is reversed compared to WaitForConnection()
// in order to avoid deadlock.
m_outboundPipe = open(m_outPipeName, O_WRONLY);
while (-1 == (m_outboundPipe = open(m_outPipeName, O_WRONLY)) && errno == EINTR);
if (m_outboundPipe == INVALID_PIPE)
{
return false;
}

m_inboundPipe = open(m_inPipeName, O_RDONLY);
while (-1 == (m_inboundPipe = open(m_inPipeName, O_RDONLY)) && errno == EINTR);
if (m_inboundPipe == INVALID_PIPE)
{
close(m_outboundPipe);
Expand All @@ -84,13 +88,13 @@ bool TwoWayPipe::WaitForConnection()
if (m_state != Created)
return false;

m_inboundPipe = open(m_inPipeName, O_RDONLY);
while (-1 == (m_inboundPipe = open(m_inPipeName, O_RDONLY)) && errno == EINTR);
if (m_inboundPipe == INVALID_PIPE)
{
return false;
}

m_outboundPipe = open(m_outPipeName, O_WRONLY);
while (-1 == (m_outboundPipe = open(m_outPipeName, O_WRONLY)) && errno == EINTR);
if (m_outboundPipe == INVALID_PIPE)
{
close(m_inboundPipe);
Expand All @@ -113,8 +117,10 @@ int TwoWayPipe::Read(void *buffer, DWORD bufferSize)
int bytesRead;
int cb = bufferSize;

while ((bytesRead = (int)read(m_inboundPipe, buffer, cb)) > 0)
while (true)
{
while (-1 == (bytesRead = (int)read(m_inboundPipe, buffer, cb)) && errno == EINTR);
if (bytesRead <= 0) break;
totalBytesRead += bytesRead;
_ASSERTE(totalBytesRead <= (int)bufferSize);
if (totalBytesRead >= (int)bufferSize)
Expand All @@ -140,8 +146,10 @@ int TwoWayPipe::Write(const void *data, DWORD dataSize)
int bytesWritten;
int cb = dataSize;

while ((bytesWritten = (int)write(m_outboundPipe, data, cb)) > 0)
while (true)
{
while (-1 == (bytesWritten = (int)write(m_outboundPipe, data, cb)) && errno == EINTR);
if (bytesWritten <= 0) break;
totalBytesWritten += bytesWritten;
_ASSERTE(totalBytesWritten <= (int)dataSize);
if (totalBytesWritten >= (int)dataSize)
Expand All @@ -166,8 +174,8 @@ bool TwoWayPipe::Disconnect()

if (m_state == ServerConnected || m_state == Created)
{
unlink(m_inPipeName);
unlink(m_outPipeName);
while (-1 == unlink(m_inPipeName) && errno == EINTR);
while (-1 == unlink(m_outPipeName) && errno == EINTR);
}

m_state = NotInitialized;
Expand All @@ -178,6 +186,6 @@ bool TwoWayPipe::Disconnect()
// and semaphores when the debugger detects the debuggee process exited.
void TwoWayPipe::CleanupTargetProcess()
{
unlink(m_inPipeName);
unlink(m_outPipeName);
while (-1 == unlink(m_inPipeName) && errno == EINTR);
while (-1 == unlink(m_outPipeName) && errno == EINTR);
}
3 changes: 2 additions & 1 deletion src/coreclr/gc/unix/cgroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ class CGroup
#else

struct statfs stats;
int result = statfs("/sys/fs/cgroup", &stats);
int result;
while (-1 == (result = statfs("/sys/fs/cgroup", &stats)) && errno == EINTR);
if (result != 0)
return 0;

Expand Down
12 changes: 10 additions & 2 deletions src/coreclr/gc/unix/numasupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,19 @@ static int GetNodeNum(const char* path, bool firstOnly)
struct dirent *entry;
int result = -1;

dir = opendir(path);
while ((dir = opendir(path)) == nullptr && errno == EINTR);
if (dir)
{
while ((entry = readdir(dir)) != NULL)
while (true)
{
do
{
errno = 0;
entry = readdir(dir);
}
while (entry == nullptr && errno == EINTR);
if (entry == nullptr) break;

if (strncmp(entry->d_name, "node", STRING_LENGTH("node")))
continue;

Expand Down
25 changes: 20 additions & 5 deletions src/coreclr/hosts/corerun/corerun.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,9 @@ namespace pal
{
// Check if the specified path exists
struct stat sb;
if (stat(file_path, &sb) == -1)
int result;
while (-1 == (result = stat(file_path, &sb)) && errno == EINTR);
if (result == -1)
{
perror(W("Path not found"));
return false;
Expand All @@ -467,12 +469,15 @@ namespace pal

inline bool try_map_file_readonly(const char* path, void** mapped, int64_t* size)
{
int fd = open(path, O_RDONLY);
int fd;
while (-1 == (fd = open(path, O_RDONLY)) && errno == EINTR);
if (fd == -1)
return false;

struct stat buf;
if (fstat(fd, &buf) == -1)
int fstat_result;
while (-1 == (fstat_result = fstat(fd, &buf)) && errno == EINTR);
if (fstat_result == -1)
{
close(fd);
return false;
Expand Down Expand Up @@ -506,16 +511,26 @@ namespace pal
assert(ext != nullptr);
const size_t ext_len = pal::strlen(ext);

DIR* dir = opendir(directory.c_str());
DIR* dir;
while ((dir = opendir(directory.c_str())) == nullptr && errno == EINTR);

if (dir == nullptr)
return {};

stringstream_t file_list;

// For all entries in the directory
struct dirent* entry;
while ((entry = readdir(dir)) != nullptr)
while (true)
{
do
{
errno = 0;
entry = readdir(dir);
}
while (entry == nullptr && errno == EINTR);
if (entry == nullptr) break;

#if HAVE_DIRENT_D_TYPE
int dirEntryType = entry->d_type;
#else
Expand Down
Loading
Loading