fix: Multiple memory corruption issues
This commit is contained in:
parent
99142525b6
commit
f587710d1c
@ -880,9 +880,9 @@ namespace hex {
|
|||||||
s_fontSize = size;
|
s_fontSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static AutoReset<std::unique_ptr<ImFontAtlas>> s_fontAtlas;
|
static AutoReset<std::shared_ptr<ImFontAtlas>> s_fontAtlas;
|
||||||
void setFontAtlas(ImFontAtlas* fontAtlas) {
|
void setFontAtlas(ImFontAtlas* fontAtlas) {
|
||||||
s_fontAtlas = std::unique_ptr<ImFontAtlas>(fontAtlas);
|
s_fontAtlas = std::unique_ptr<ImFontAtlas, void(*)(ImFontAtlas*)>(fontAtlas, IM_DELETE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ImFont *s_boldFont = nullptr;
|
static ImFont *s_boldFont = nullptr;
|
||||||
|
@ -17,18 +17,25 @@ namespace hex {
|
|||||||
AutoReset<std::string> s_imageTheme;
|
AutoReset<std::string> s_imageTheme;
|
||||||
AutoReset<std::string> s_currTheme;
|
AutoReset<std::string> s_currTheme;
|
||||||
|
|
||||||
|
std::mutex s_themeMutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ThemeManager::addThemeHandler(const std::string &name, const ColorMap &colorMap, const std::function<ImColor(u32)> &getFunction, const std::function<void(u32, ImColor)> &setFunction) {
|
void ThemeManager::addThemeHandler(const std::string &name, const ColorMap &colorMap, const std::function<ImColor(u32)> &getFunction, const std::function<void(u32, ImColor)> &setFunction) {
|
||||||
|
std::unique_lock lock(s_themeMutex);
|
||||||
|
|
||||||
(*s_themeHandlers)[name] = { colorMap, getFunction, setFunction };
|
(*s_themeHandlers)[name] = { colorMap, getFunction, setFunction };
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThemeManager::addStyleHandler(const std::string &name, const StyleMap &styleMap) {
|
void ThemeManager::addStyleHandler(const std::string &name, const StyleMap &styleMap) {
|
||||||
|
std::unique_lock lock(s_themeMutex);
|
||||||
|
|
||||||
(*s_styleHandlers)[name] = { styleMap };
|
(*s_styleHandlers)[name] = { styleMap };
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThemeManager::addTheme(const std::string &content) {
|
void ThemeManager::addTheme(const std::string &content) {
|
||||||
|
std::unique_lock lock(s_themeMutex);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto theme = nlohmann::json::parse(content);
|
auto theme = nlohmann::json::parse(content);
|
||||||
|
|
||||||
@ -106,6 +113,8 @@ namespace hex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ThemeManager::changeTheme(std::string name) {
|
void ThemeManager::changeTheme(std::string name) {
|
||||||
|
std::unique_lock lock(s_themeMutex);
|
||||||
|
|
||||||
if (!s_themes->contains(name)) {
|
if (!s_themes->contains(name)) {
|
||||||
if (s_themes->empty()) {
|
if (s_themes->empty()) {
|
||||||
return;
|
return;
|
||||||
@ -168,12 +177,12 @@ namespace hex {
|
|||||||
const float scale = style.needsScaling ? 1_scaled : 1.0F;
|
const float scale = style.needsScaling ? 1_scaled : 1.0F;
|
||||||
|
|
||||||
if (value.is_number_float()) {
|
if (value.is_number_float()) {
|
||||||
if (const auto newValue = std::get_if<float*>(&style.value); newValue != nullptr)
|
if (const auto newValue = std::get_if<float*>(&style.value); newValue != nullptr && *newValue != nullptr)
|
||||||
**newValue = value.get<float>() * scale;
|
**newValue = value.get<float>() * scale;
|
||||||
else
|
else
|
||||||
log::warn("Style variable '{}' was of type ImVec2 but a float was expected.", name);
|
log::warn("Style variable '{}' was of type ImVec2 but a float was expected.", name);
|
||||||
} else if (value.is_array() && value.size() == 2 && value[0].is_number_float() && value[1].is_number_float()) {
|
} else if (value.is_array() && value.size() == 2 && value[0].is_number_float() && value[1].is_number_float()) {
|
||||||
if (const auto newValue = std::get_if<ImVec2*>(&style.value); newValue != nullptr)
|
if (const auto newValue = std::get_if<ImVec2*>(&style.value); newValue != nullptr && *newValue != nullptr)
|
||||||
**newValue = ImVec2(value[0].get<float>() * scale, value[1].get<float>() * scale);
|
**newValue = ImVec2(value[0].get<float>() * scale, value[1].get<float>() * scale);
|
||||||
else
|
else
|
||||||
log::warn("Style variable '{}' was of type float but a ImVec2 was expected.", name);
|
log::warn("Style variable '{}' was of type float but a ImVec2 was expected.", name);
|
||||||
@ -191,6 +200,8 @@ namespace hex {
|
|||||||
hex::log::error("Theme '{}' has invalid image theme!", name);
|
hex::log::error("Theme '{}' has invalid image theme!", name);
|
||||||
s_imageTheme = "dark";
|
s_imageTheme = "dark";
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
s_imageTheme = "dark";
|
||||||
}
|
}
|
||||||
|
|
||||||
s_currTheme = name;
|
s_currTheme = name;
|
||||||
@ -211,6 +222,8 @@ namespace hex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ThemeManager::reset() {
|
void ThemeManager::reset() {
|
||||||
|
std::unique_lock lock(s_themeMutex);
|
||||||
|
|
||||||
s_themes->clear();
|
s_themes->clear();
|
||||||
s_styleHandlers->clear();
|
s_styleHandlers->clear();
|
||||||
s_themeHandlers->clear();
|
s_themeHandlers->clear();
|
||||||
|
@ -57,16 +57,20 @@ namespace hex::init {
|
|||||||
// Terminate all asynchronous tasks
|
// Terminate all asynchronous tasks
|
||||||
TaskManager::exit();
|
TaskManager::exit();
|
||||||
|
|
||||||
// Unlock font atlas so it can be deleted in case of a crash
|
// Unlock font atlas, so it can be deleted in case of a crash
|
||||||
if (ImGui::GetCurrentContext() != nullptr)
|
if (ImGui::GetCurrentContext() != nullptr) {
|
||||||
ImGui::GetIO().Fonts->Locked = false;
|
if (ImGui::GetIO().Fonts != nullptr) {
|
||||||
|
ImGui::GetIO().Fonts->Locked = false;
|
||||||
|
ImGui::GetIO().Fonts = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Print a nice message if a crash happened while cleaning up resources
|
// Print a nice message if a crash happened while cleaning up resources
|
||||||
// To the person fixing this:
|
// To the person fixing this:
|
||||||
// ALWAYS wrap static heap allocated objects inside libimhex such as std::vector, std::string, std::function, etc. in a AutoReset<T>
|
// ALWAYS wrap static heap allocated objects inside libimhex such as std::vector, std::string, std::function, etc. in a AutoReset<T>
|
||||||
// e.g `AutoReset<std::vector<MyStruct>> m_structs;`
|
// e.g `AutoReset<std::vector<MyStruct>> m_structs;`
|
||||||
//
|
//
|
||||||
// The reason this is necessary is because each plugin / dynamic library gets its own instance of `std::allocator`
|
// The reason this is necessary because each plugin / dynamic library gets its own instance of `std::allocator`
|
||||||
// which will try to free the allocated memory when the object is destroyed. However since the storage is static, this
|
// which will try to free the allocated memory when the object is destroyed. However since the storage is static, this
|
||||||
// will happen only when libimhex is unloaded after main() returns. At this point all plugins have been unloaded already so
|
// will happen only when libimhex is unloaded after main() returns. At this point all plugins have been unloaded already so
|
||||||
// the std::allocator will try to free memory in a heap that does not exist anymore which will cause a crash.
|
// the std::allocator will try to free memory in a heap that does not exist anymore which will cause a crash.
|
||||||
@ -81,6 +85,7 @@ namespace hex::init {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ImHexApi::System::impl::cleanup();
|
ImHexApi::System::impl::cleanup();
|
||||||
|
|
||||||
EventImHexClosing::post();
|
EventImHexClosing::post();
|
||||||
EventManager::clear();
|
EventManager::clear();
|
||||||
|
|
||||||
|
@ -985,7 +985,6 @@ namespace hex {
|
|||||||
ImGui_ImplOpenGL3_Shutdown();
|
ImGui_ImplOpenGL3_Shutdown();
|
||||||
ImGui_ImplGlfw_Shutdown();
|
ImGui_ImplGlfw_Shutdown();
|
||||||
|
|
||||||
ImNodes::DestroyContext();
|
|
||||||
ImPlot::DestroyContext();
|
ImPlot::DestroyContext();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user