Skip to content

Commit c1d83df

Browse files
committed
FEXCore/Config: Late initialize two objects
These need to be late initialized because they allocate memory and register an `atexit` handler to deallocate. Removes an `atexit` registration that contributes to crashing on exit.
1 parent 251a3ba commit c1d83df

4 files changed

Lines changed: 25 additions & 19 deletions

File tree

FEXCore/Source/Interface/Config/Config.cpp

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,22 +49,24 @@ enum Paths {
4949
PATH_CONFIG_TELEMETRY_FOLDER,
5050
PATH_LAST,
5151
};
52-
static std::array<fextl::string, Paths::PATH_LAST> Paths;
52+
using PathsType = std::array<fextl::string, Paths::PATH_LAST>;
53+
static PathsType* Paths {};
54+
alignas(alignof(PathsType)) static char PathsPlacement[sizeof(PathsType)];
5355

5456
void SetDataDirectory(const std::string_view Path, bool Global) {
55-
Paths[PATH_DATA_DIR_LOCAL + Global] = Path;
57+
(*Paths)[PATH_DATA_DIR_LOCAL + Global] = Path;
5658
}
5759

5860
void SetConfigDirectory(const std::string_view Path, bool Global) {
59-
Paths[PATH_CONFIG_DIR_LOCAL + Global] = Path;
61+
(*Paths)[PATH_CONFIG_DIR_LOCAL + Global] = Path;
6062
}
6163

6264
void SetConfigFileLocation(const std::string_view Path, bool Global) {
63-
Paths[PATH_CONFIG_FILE_LOCAL + Global] = Path;
65+
(*Paths)[PATH_CONFIG_FILE_LOCAL + Global] = Path;
6466
}
6567

6668
const fextl::string& GetTelemetryDirectory() {
67-
auto& Path = Paths[PATH_CONFIG_TELEMETRY_FOLDER];
69+
auto& Path = (*Paths)[PATH_CONFIG_TELEMETRY_FOLDER];
6870
if (Path.empty()) {
6971
FEX_CONFIG_OPT(TelemetryDirectory, TELEMETRYDIRECTORY);
7072
if (!TelemetryDirectory().empty()) {
@@ -79,15 +81,15 @@ const fextl::string& GetTelemetryDirectory() {
7981
}
8082

8183
const fextl::string& GetDataDirectory(bool Global) {
82-
return Paths[PATH_DATA_DIR_LOCAL + Global];
84+
return (*Paths)[PATH_DATA_DIR_LOCAL + Global];
8385
}
8486

8587
const fextl::string& GetConfigDirectory(bool Global) {
86-
return Paths[PATH_CONFIG_DIR_LOCAL + Global];
88+
return (*Paths)[PATH_CONFIG_DIR_LOCAL + Global];
8789
}
8890

8991
const fextl::string& GetConfigFileLocation(bool Global) {
90-
return Paths[PATH_CONFIG_FILE_LOCAL + Global];
92+
return (*Paths)[PATH_CONFIG_FILE_LOCAL + Global];
9193
}
9294

9395
fextl::string GetApplicationConfig(const std::string_view Program, bool Global) {
@@ -110,7 +112,9 @@ fextl::string GetApplicationConfig(const std::string_view Program, bool Global)
110112
return fextl::fmt::format("{}{}.json", ConfigFile, Program);
111113
}
112114

113-
static fextl::map<FEXCore::Config::LayerType, fextl::unique_ptr<FEXCore::Config::Layer>> ConfigLayers;
115+
using ConfigLayerType = fextl::map<FEXCore::Config::LayerType, fextl::unique_ptr<FEXCore::Config::Layer>>;
116+
static ConfigLayerType* ConfigLayers;
117+
alignas(alignof(ConfigLayerType)) static char ConfigLayersPlacement[sizeof(ConfigLayerType)];
114118
class MetaLayer;
115119
static FEXCore::Config::MetaLayer* Meta {};
116120

@@ -172,8 +176,8 @@ void MetaLayer::Load() {
172176
OptionMap.clear();
173177

174178
for (auto CurrentLayer = LoadOrder.begin(); CurrentLayer != LoadOrder.end(); ++CurrentLayer) {
175-
auto it = ConfigLayers.find(*CurrentLayer);
176-
if (it != ConfigLayers.end() && *CurrentLayer != Type) {
179+
auto it = ConfigLayers->find(*CurrentLayer);
180+
if (it != ConfigLayers->end() && *CurrentLayer != Type) {
177181
// Merge this layer's options to this layer
178182
MergeConfigMap(it->second->GetOptionMap());
179183
}
@@ -234,19 +238,21 @@ void MetaLayer::MergeConfigMap(const LayerOptions& Options) {
234238
}
235239

236240
void Initialize() {
241+
Paths = new (PathsPlacement) PathsType {};
242+
ConfigLayers = new (ConfigLayersPlacement) ConfigLayerType {};
237243
AddLayer(fextl::make_unique<MetaLayer>(FEXCore::Config::LayerType::LAYER_TOP));
238-
Meta = dynamic_cast<MetaLayer*>(ConfigLayers.begin()->second.get());
244+
Meta = dynamic_cast<MetaLayer*>(ConfigLayers->begin()->second.get());
239245
}
240246

241247
void Shutdown() {
242-
ConfigLayers.clear();
248+
ConfigLayers->clear();
243249
Meta = nullptr;
244250
}
245251

246252
void Load() {
247253
for (auto CurrentLayer = LoadOrder.begin(); CurrentLayer != LoadOrder.end(); ++CurrentLayer) {
248-
auto it = ConfigLayers.find(*CurrentLayer);
249-
if (it != ConfigLayers.end()) {
254+
auto it = ConfigLayers->find(*CurrentLayer);
255+
if (it != ConfigLayers->end()) {
250256
it->second->Load();
251257
}
252258
}
@@ -416,7 +422,7 @@ void ReloadMetaLayer() {
416422
}
417423

418424
void AddLayer(fextl::unique_ptr<FEXCore::Config::Layer> _Layer) {
419-
ConfigLayers.emplace(_Layer->GetLayerType(), std::move(_Layer));
425+
ConfigLayers->emplace(_Layer->GetLayerType(), std::move(_Layer));
420426
}
421427

422428
bool Exists(ConfigOption Option) {

Source/Common/Config.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,8 @@ ApplicationNames GetApplicationNames(const fextl::vector<fextl::string>& Args, b
451451

452452
void LoadConfig(fextl::string ProgramName, char** const envp, const PortableInformation& PortableInfo) {
453453
const bool IsPortable = PortableInfo.IsPortable;
454-
FEX::Config::InitializeConfigs(PortableInfo);
455454
FEXCore::Config::Initialize();
455+
FEX::Config::InitializeConfigs(PortableInfo);
456456
if (!IsPortable) {
457457
FEXCore::Config::AddLayer(CreateGlobalMainLayer());
458458
}

Source/Tools/FEXGetConfig/Main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ TSOEmulationFacts GetTSOEmulationFacts() {
9595
} // namespace
9696

9797
int main(int argc, char** argv, char** envp) {
98-
FEX::Config::InitializeConfigs(FEX::Config::PortableInformation {});
9998
FEXCore::Config::Initialize();
99+
FEX::Config::InitializeConfigs(FEX::Config::PortableInformation {});
100100
FEXCore::Config::AddLayer(FEX::Config::CreateGlobalMainLayer());
101101
FEXCore::Config::AddLayer(FEX::Config::CreateMainLayer());
102102
// No FEX arguments passed through command line

Source/Tools/TestHarnessRunner/TestHarnessRunner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ int main(int argc, char** argv, char** const envp) {
195195
LogMan::Throw::InstallHandler(AssertHandler);
196196
LogMan::Msg::InstallHandler(MsgHandler);
197197

198-
FEX::Config::InitializeConfigs(FEX::Config::PortableInformation {});
199198
FEXCore::Config::Initialize();
199+
FEX::Config::InitializeConfigs(FEX::Config::PortableInformation {});
200200
FEXCore::Config::AddLayer(FEX::Config::CreateEnvironmentLayer(envp));
201201
FEXCore::Config::Load();
202202

0 commit comments

Comments
 (0)