Skip to content

Commit

Permalink
Merge pull request #3507 from Sonicadvance1/fd_tracking_check
Browse files Browse the repository at this point in the history
FEXLoader: Add some debug-only tracking for FEX owned FDs
  • Loading branch information
Sonicadvance1 authored Mar 27, 2024
2 parents 7f90ca5 + 60755ac commit 79454ed
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 2 deletions.
13 changes: 11 additions & 2 deletions Source/Tools/FEXLoader/FEXLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ desc: Glues the ELF loader, FEXCore and LinuxSyscalls to launch an elf under fex

namespace {
static bool SilentLog;
static int OutputFD {STDERR_FILENO};
static int OutputFD {-1};
static bool ExecutedWithFD {false};

void MsgHandler(LogMan::DebugLevels Level, char const *Message) {
Expand All @@ -88,7 +88,7 @@ void AssertHandler(char const *Message) {
} // Anonymous namespace

namespace FEXServerLogging {
int FEXServerFD{};
int FEXServerFD{-1};
void MsgHandler(LogMan::DebugLevels Level, char const *Message) {
FEXServerClient::MsgHandler(FEXServerFD, Level, Message);
}
Expand Down Expand Up @@ -456,6 +456,15 @@ int main(int argc, char **argv, char **const envp) {
auto SyscallHandler = Loader.Is64BitMode() ? FEX::HLE::x64::CreateHandler(CTX.get(), SignalDelegation.get())
: FEX::HLE::x32::CreateHandler(CTX.get(), SignalDelegation.get(), std::move(Allocator));

// Now that we have the syscall handler. Track some FDs that are FEX owned.
if (OutputFD != -1) {
SyscallHandler->FM.TrackFEXFD(OutputFD);
}
SyscallHandler->FM.TrackFEXFD(FEXServerClient::GetServerFD());
if (FEXServerLogging::FEXServerFD != -1) {
SyscallHandler->FM.TrackFEXFD(FEXServerLogging::FEXServerFD);
}

{
// Load VDSO in to memory prior to mapping our ELFs.
void* VDSOBase = FEX::VDSO::LoadVDSOThunks(Loader.Is64BitMode(), SyscallHandler.get());
Expand Down
18 changes: 18 additions & 0 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ FileManager::FileManager(FEXCore::Context::Context *ctx)
if (RootFSFD == -1) {
RootFSFD = AT_FDCWD;
}
else {
TrackFEXFD(RootFSFD);
}
}

fextl::unordered_map<fextl::string, ThunkDBObject> ThunkDB;
Expand Down Expand Up @@ -571,13 +574,28 @@ uint64_t FileManager::Open(const char *pathname, int flags, uint32_t mode) {
}

uint64_t FileManager::Close(int fd) {
#if defined(ASSERTIONS_ENABLED) && ASSERTIONS_ENABLED
if (CheckIfFDInTrackedSet(fd)) {
LogMan::Msg::EFmt("{} closing FEX FD {}", __func__, fd);
RemoveFEXFD(fd);
}
#endif

return ::close(fd);
}

uint64_t FileManager::CloseRange(unsigned int first, unsigned int last, unsigned int flags) {
#ifndef CLOSE_RANGE_CLOEXEC
#define CLOSE_RANGE_CLOEXEC (1U << 2)
#endif
#if defined(ASSERTIONS_ENABLED) && ASSERTIONS_ENABLED
if (!(flags & CLOSE_RANGE_CLOEXEC) &&
CheckIfFDRangeInTrackedSet(first, last)) {
LogMan::Msg::EFmt("{} closing FEX FDs in range ({}, {})", __func__, first, last);
RemoveFEXFDRange(first, last);
}
#endif

return ::syscall(SYSCALL_DEF(close_range), first, last, flags);
}

Expand Down
46 changes: 46 additions & 0 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,53 @@ class FileManager final {

bool SupportsProcFSInterpreterPath() const { return SupportsProcFSInterpreter; }

#if defined(ASSERTIONS_ENABLED) && ASSERTIONS_ENABLED
void TrackFEXFD(int FD) noexcept {
std::lock_guard lk(FEXTrackingFDMutex);
FEXTrackingFDs.emplace(FD);
}

void RemoveFEXFD(int FD) noexcept {
std::lock_guard lk(FEXTrackingFDMutex);
FEXTrackingFDs.erase(FD);
}

void RemoveFEXFDRange(int begin, int end) noexcept {
std::lock_guard lk(FEXTrackingFDMutex);

std::erase_if(FEXTrackingFDs, [begin, end](int FD) {
return FD >= begin && (FD <= end || end == -1);
});
}

bool CheckIfFDInTrackedSet(int FD) noexcept {
std::lock_guard lk(FEXTrackingFDMutex);
return FEXTrackingFDs.contains(FD);
}

bool CheckIfFDRangeInTrackedSet(int begin, int end) noexcept {
std::lock_guard lk(FEXTrackingFDMutex);
// Just linear scan since the number of tracking FDs is low.
for (auto it : FEXTrackingFDs) {
if (it >= begin && (it <= end || end == -1)) return true;
}
return false;
}

#else
void TrackFEXFD(int FD) const noexcept {}
bool CheckIfFDInTrackedSet(int FD) const noexcept { return false; }
void RemoveFEXFD(int FD) const noexcept {}
void RemoveFEXFDRange(int begin, int end) const noexcept {}
bool CheckIfFDRangeInTrackedSet(int begin, int end) const noexcept { return false; }
#endif

private:
#if defined(ASSERTIONS_ENABLED) && ASSERTIONS_ENABLED
std::mutex FEXTrackingFDMutex;
fextl::set<int> FEXTrackingFDs;
#endif

bool RootFSPathExists(const char* Filepath);

struct ThunkDBObject {
Expand Down

0 comments on commit 79454ed

Please sign in to comment.