mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Hold the shutdown lock across all of CPU_Shutdown
It was only held across Memory::Shutdown(), but everything else in there frees state the debugger UIs read from other threads - kernel objects (__KernelShutdown), the symbol map, replacements - so a Win32 debugger window painting while a game is reset could read freed memory. It's recursive, so the nested acquire in Memory::Shutdown() is unaffected. No lock-order risk: on the paths where CPU_Shutdown already runs under g_frameMutex it now takes these in the same frame-then-shutdown order the GUI side uses, and on the paths where it doesn't (EmuScreen::sendMessage, ProcessScreenSwitches - both above where NativeFrame takes the guard) it takes only this one. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01GZq8ZtJmFY7bkX5FVkr3P9
This commit is contained in:
1 parent
933d39406a
commit
4a10fa2808
1 file changed
+6
@@ -568,6 +568,12 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin
|
||||
}
|
||||
|
||||
void CPU_Shutdown(bool success) {
|
||||
// Held across the whole teardown, not just Memory::Shutdown() further down. Everything below
|
||||
// frees state the debugger UIs read from other threads - kernel objects, the symbol map, the
|
||||
// memory map - and this is the lock they take to be sure none of it goes away mid-read. See
|
||||
// Memory::Lock(); it's recursive, so the nested acquire in Memory::Shutdown() is fine.
|
||||
Memory::MemoryInitedLock coreLock = Memory::Lock();
|
||||
|
||||
UninstallExceptionHandler();
|
||||
|
||||
GPURecord::Replay_Unload();
|
||||
|
||||
Reference in new issue
Block a user