Mark code regions that require glibc memory allocations.

This ensures that when we enable glibc fault testing these sections
won't break CI.
This commit is contained in:
Ryan Houdek 2023-03-17 20:12:25 -07:00
parent 43e6d398b6
commit 465ecd9b19
12 changed files with 70 additions and 19 deletions

View File

@ -70,6 +70,7 @@ namespace FEXCore::Paths {
*EntryCache = *CachePath + "/EntryCache/";
std::error_code ec{};
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
// Ensure the folder structure is created for our Data
if (!std::filesystem::exists(*EntryCache, ec) &&
!std::filesystem::create_directories(*EntryCache, ec)) {

View File

@ -4,6 +4,7 @@
#include "Utils/FileLoading.h"
#include <FEXCore/Config/Config.h>
#include <FEXCore/Utils/Allocator.h>
#include <FEXCore/Utils/CPUInfo.h>
#include <FEXCore/Utils/LogManager.h>
#include <FEXCore/fextl/list.h>
@ -144,6 +145,8 @@ namespace JSON {
// Ensure the folder structure is created for our configuration
std::error_code ec{};
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
if (!std::filesystem::exists(ConfigDir, ec) &&
!std::filesystem::create_directories(ConfigDir, ec)) {
// Let's go local in this case
@ -176,6 +179,8 @@ namespace JSON {
fextl::string ConfigFile = GetConfigDirectory(Global);
std::error_code ec{};
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
if (!Global &&
!std::filesystem::exists(ConfigFile, ec) &&
!std::filesystem::create_directories(ConfigFile, ec)) {
@ -346,8 +351,11 @@ namespace JSON {
return PathName;
}
// Expand relative path to absolute
Path = std::filesystem::absolute(Path);
{
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
// Expand relative path to absolute
Path = std::filesystem::absolute(Path);
}
// Only return if it exists
std::error_code ec{};
@ -379,8 +387,9 @@ namespace JSON {
return {};
}
fextl::string FindContainer() {
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
// We only support pressure-vessel at the moment
const static fextl::string ContainerManager = "/run/host/container-manager";
if (std::filesystem::exists(ContainerManager)) {
@ -396,6 +405,8 @@ namespace JSON {
}
fextl::string FindContainerPrefix() {
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
// We only support pressure-vessel at the moment
const static fextl::string ContainerManager = "/run/host/container-manager";
if (std::filesystem::exists(ContainerManager)) {
@ -459,6 +470,7 @@ namespace JSON {
fextl::string ContainerPrefix { FindContainerPrefix() };
auto ExpandPathIfExists = [&ContainerPrefix](FEXCore::Config::ConfigOption Config, fextl::string PathName) {
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
auto NewPath = ExpandPath(ContainerPrefix, PathName);
if (!NewPath.empty()) {
FEXCore::Config::EraseSet(Config, NewPath);
@ -722,6 +734,7 @@ namespace JSON {
EnvMap[Key]=Value;
}
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
std::function GetVar = [=](const std::string_view id) -> std::optional<std::string_view> {
if (EnvMap.find(id) != EnvMap.end())
return EnvMap.at(id);

View File

@ -371,6 +371,7 @@ namespace FEXCore::IR {
}
AOTIRCacheEntry *AOTIRCaptureCache::LoadAOTIRCacheEntry(const fextl::string &filename) {
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
fextl::string base_filename = fextl::string_from_path(std::filesystem::path(filename).filename());
if (!base_filename.empty()) {

View File

@ -29,6 +29,7 @@ namespace FEXCore::Telemetry {
// Ensure the folder structure is created for our configuration
std::error_code ec{};
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
if (!std::filesystem::exists(DataDirectory, ec) &&
!std::filesystem::create_directories(DataDirectory, ec)) {
LogMan::Msg::IFmt("Couldn't create telemetry Folder");
@ -40,6 +41,7 @@ namespace FEXCore::Telemetry {
DataDirectory += "Telemetry/" + ApplicationName + ".telem";
std::error_code ec{};
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
if (std::filesystem::exists(DataDirectory, ec)) {
// If the file exists, retain a single backup
auto Backup = DataDirectory + ".1";

View File

@ -97,9 +97,14 @@ namespace FEXCore::Threads {
, UserArg {Arg} {
pthread_attr_t Attr{};
Stack = AllocateStackObject(STACK_SIZE);
// pthreads allocates its dtv region behind our back and there is nothing we can do about it.
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
AddStackToLivePool(Stack, STACK_SIZE);
pthread_attr_init(&Attr);
pthread_attr_setstack(&Attr, Stack, STACK_SIZE);
// TODO: Thread creation should be using this instead.
// Causes Steam to crash early though.
// pthread_create(&Thread, &Attr, InitializeThread, this);
pthread_create(&Thread, &Attr, Func, Arg);
pthread_attr_destroy(&Attr);
@ -155,6 +160,10 @@ namespace FEXCore::Threads {
// Put the stack back in to the stack pool
Thread->FreeStack();
// TLS/DTV teardown is something FEX can't control. Disable glibc checking when we leave a pthread.
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator::HardDisable();
return Result;
}

View File

@ -14,6 +14,7 @@ namespace FEX::ArgLoader {
static std::string Version = "FEX-Emu (" GIT_DESCRIBE_STRING ") ";
void FEX::ArgLoader::ArgLoader::Load() {
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
optparse::OptionParser Parser{};
Parser.version(Version);
optparse::OptionGroup CPUGroup(Parser, "CPU Core options");

View File

@ -44,6 +44,8 @@ namespace FEX::Config {
}
fextl::string RecoverGuestProgramFilename(fextl::string Program, bool ExecFDInterp, const std::string_view ProgramFDFromEnv) {
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
// If executed with a FEX FD then the Program argument might be empty.
// In this case we need to scan the FD node to recover the application binary that exists on disk.
// Only do this if the Program argument is empty, since we would prefer the application's expectation
@ -137,6 +139,7 @@ namespace FEX::Config {
Args[0] = RecoverGuestProgramFilename(std::move(Args[0]), ExecFDInterp, ProgramFDFromEnv);
fextl::string& Program = Args[0];
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
bool Wine = false;
std::filesystem::path ProgramName;
for (size_t CurrentProgramNameIndex = 0; CurrentProgramNameIndex < Args.size(); ++CurrentProgramNameIndex) {

View File

@ -1,5 +1,6 @@
#pragma once
#include <FEXCore/Utils/Allocator.h>
#include <FEXCore/Utils/LogManager.h>
#include <FEXCore/fextl/string.h>
@ -13,6 +14,7 @@ namespace FEX {
[[maybe_unused]]
static
std::optional<fextl::string> get_fdpath(int fd) {
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
char SymlinkPath[PATH_MAX];
std::filesystem::path Path = std::filesystem::path("/proc/self/fd") / std::to_string(fd);
int Result = readlinkat(AT_FDCWD, Path.c_str(), SymlinkPath, sizeof(SymlinkPath));

View File

@ -211,6 +211,7 @@ namespace FEXServerClient {
return -1;
}
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
fextl::string FEXServerPath = fextl::string_from_path(std::filesystem::path(InterpreterPath).parent_path()) + "/FEXServer";
// Check if a local FEXServer next to FEXInterpreter exists
// If it does then it takes priority over the installed one

View File

@ -123,6 +123,7 @@ namespace FEXServerLogging {
}
void InterpreterHandler(fextl::string *Filename, fextl::string const &RootFS, fextl::vector<fextl::string> *args) {
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
// Open the file pointer to the filename and see if we need to find an interpreter
std::fstream File(fextl::string_from_string(*Filename), std::fstream::in | std::fstream::binary);
@ -178,6 +179,7 @@ void RootFSRedirect(fextl::string *Filename, fextl::string const &RootFS) {
auto RootFSLink = ELFCodeLoader::ResolveRootfsFile(*Filename, RootFS);
std::error_code ec{};
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
if (std::filesystem::exists(RootFSLink, ec)) {
*Filename = RootFSLink;
}
@ -293,11 +295,16 @@ int main(int argc, char **argv, char **const envp) {
InterpreterHandler(&Program.ProgramPath, LDPath(), &Args);
std::error_code ec{};
if (!ExecutedWithFD && !FEXFD && !std::filesystem::exists(Program.ProgramPath, ec)) {
// Early exit if the program passed in doesn't exist
// Will prevent a crash later
fmt::print(stderr, "{}: command not found\n", Program.ProgramPath);
return -ENOEXEC;
{
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
if (!ExecutedWithFD && !FEXFD && !std::filesystem::exists(Program.ProgramPath, ec)) {
// Early exit if the program passed in doesn't exist
// Will prevent a crash later
fmt::print(stderr, "{}: command not found\n", Program.ProgramPath);
FEXCore::Allocator::ClearFaultEvaluate();
return -ENOEXEC;
}
}
uint32_t KernelVersion = FEX::HLE::SyscallHandler::CalculateHostKernelVersion();
@ -342,7 +349,10 @@ int main(int argc, char **argv, char **const envp) {
FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_APP_CONFIG_NAME, "<Anonymous>");
}
else {
FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_APP_FILENAME, std::filesystem::canonical(Program.ProgramPath).string());
{
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_APP_FILENAME, std::filesystem::canonical(Program.ProgramPath).string());
}
FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_APP_CONFIG_NAME, Program.ProgramName);
}
FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_IS64BIT_MODE, Loader.Is64BitMode() ? "1" : "0");
@ -402,18 +412,23 @@ int main(int argc, char **argv, char **const envp) {
auto SyscallHandler = Loader.Is64BitMode() ? FEX::HLE::x64::CreateHandler(CTX, SignalDelegation.get())
: FEX::HLE::x32::CreateHandler(CTX, SignalDelegation.get(), std::move(Allocator));
auto Mapper = std::bind_front(&FEX::HLE::SyscallHandler::GuestMmap, SyscallHandler.get());
auto Unmapper = std::bind_front(&FEX::HLE::SyscallHandler::GuestMunmap, SyscallHandler.get());
{
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
// Load VDSO in to memory prior to mapping our ELFs.
void* VDSOBase = FEX::VDSO::LoadVDSOThunks(Loader.Is64BitMode(), Mapper);
Loader.SetVDSOBase(VDSOBase);
Loader.CalculateHWCaps(CTX);
auto Mapper = std::bind_front(&FEX::HLE::SyscallHandler::GuestMmap, SyscallHandler.get());
auto Unmapper = std::bind_front(&FEX::HLE::SyscallHandler::GuestMunmap, SyscallHandler.get());
if (!Loader.MapMemory(Mapper, Unmapper)) {
// failed to map
LogMan::Msg::EFmt("Failed to map %d-bit elf file.", Loader.Is64BitMode() ? 64 : 32);
return -ENOEXEC;
// Load VDSO in to memory prior to mapping our ELFs.
void* VDSOBase = FEX::VDSO::LoadVDSOThunks(Loader.Is64BitMode(), Mapper);
Loader.SetVDSOBase(VDSOBase);
Loader.CalculateHWCaps(CTX);
if (!Loader.MapMemory(Mapper, Unmapper)) {
// failed to map
LogMan::Msg::EFmt("Failed to map %d-bit elf file.", Loader.Is64BitMode() ? 64 : 32);
FEXCore::Allocator::ClearFaultEvaluate();
return -ENOEXEC;
}
}
SyscallHandler->SetCodeLoader(&Loader);

View File

@ -764,6 +764,7 @@ namespace FEX::EmulatedFile {
}
if (!RealPathExists) {
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
Creator = FDReadCreators.find(fextl::string_from_path(std::filesystem::path(Path).lexically_normal()));
}

View File

@ -62,6 +62,7 @@ namespace FEX::HLE {
struct open_how;
static bool LoadFile(fextl::vector<char> &Data, const fextl::string &Filename) {
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
std::fstream File(fextl::string_from_string(Filename), std::ios::in);
if (!File.is_open()) {
@ -216,6 +217,7 @@ static void LoadThunkDatabase(fextl::unordered_map<fextl::string, ThunkDBObject>
FileManager::FileManager(FEXCore::Context::Context *ctx)
: EmuFD {ctx} {
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc;
auto ThunkConfigFile = ThunkConfig();