summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorDentomologist <dentomologist@gmail.com>2025-04-24 11:36:18 -0700
committerDentomologist <dentomologist@gmail.com>2025-04-25 15:29:29 -0700
commite37a1951926bb5d079e6cd8a65740b87bdafe175 (patch)
tree15df4f5050a689a660b3692bc942cb88b60d9e4f /Source
parent805307f432dba079caf7339122a07de5b90c4b47 (diff)
MainWindow: Fix use-after-free during shutdown
Remove ConfigChangedCallback in MainWindow's destructor to prevent the callback from accessing the destroyed MainWindow afterward. After MainWindow is destroyed UICommon::Shutdown calls LogManager::Shutdown which ultimately triggers any remaining callbacks. This resulted in calling MainWindow::OnHardcoreChanged, which crashed in debug builds and didn't have any obvious effect in release builds.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/DolphinQt/MainWindow.cpp4
-rw-r--r--Source/Core/DolphinQt/MainWindow.h5
2 files changed, 8 insertions, 1 deletions
diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp
index 8a766dc6b7..99d38e4d6d 100644
--- a/Source/Core/DolphinQt/MainWindow.cpp
+++ b/Source/Core/DolphinQt/MainWindow.cpp
@@ -34,6 +34,7 @@
#include <qpa/qplatformnativeinterface.h>
#endif
+#include "Common/Config/Config.h"
#include "Common/ScopeGuard.h"
#include "Common/Version.h"
#include "Common/WindowSystemInfo.h"
@@ -277,7 +278,7 @@ MainWindow::MainWindow(Core::System& system, std::unique_ptr<BootParameters> boo
if (AchievementManager::GetInstance().IsHardcoreModeActive())
Settings::Instance().SetDebugModeEnabled(false);
// This needs to trigger on both RA_HARDCORE_ENABLED and RA_ENABLED
- Config::AddConfigChangedCallback(
+ m_config_changed_callback_id = Config::AddConfigChangedCallback(
[this]() { QueueOnObject(this, [this] { this->OnHardcoreChanged(); }); });
// If hardcore is enabled when the emulator starts, make sure it turns off what it needs to
if (Config::Get(Config::RA_HARDCORE_ENABLED))
@@ -351,6 +352,7 @@ MainWindow::~MainWindow()
Settings::Instance().ResetNetPlayServer();
#ifdef USE_RETRO_ACHIEVEMENTS
+ Config::RemoveConfigChangedCallback(m_config_changed_callback_id);
AchievementManager::GetInstance().Shutdown();
#endif // USE_RETRO_ACHIEVEMENTS
diff --git a/Source/Core/DolphinQt/MainWindow.h b/Source/Core/DolphinQt/MainWindow.h
index a43f98ead0..7684d4ad16 100644
--- a/Source/Core/DolphinQt/MainWindow.h
+++ b/Source/Core/DolphinQt/MainWindow.h
@@ -11,6 +11,10 @@
#include <optional>
#include <string>
+#ifdef USE_RETRO_ACHIEVEMENTS
+#include "Common/Config/Config.h"
+#endif // USE_RETRO_ACHIEVEMENTS
+
#include "Core/Boot/Boot.h"
class QMenu;
@@ -261,6 +265,7 @@ private:
#ifdef USE_RETRO_ACHIEVEMENTS
AchievementsWindow* m_achievements_window = nullptr;
+ Config::ConfigChangedCallbackID m_config_changed_callback_id;
#endif // USE_RETRO_ACHIEVEMENTS
AssemblerWidget* m_assembler_widget;