mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Win32 debugger: take the shutdown lock everywhere core state is read
Seven GUI-thread readers held only g_frameMutex, which guards against the CPU thread mutating state but not against the core being torn down - and two of PSP_Shutdown's paths (EmuScreen::sendMessage, ProcessScreenSwitches) run outside that span entirely. CtrlThreadList::reloadThreads walking kernel objects that __KernelShutdown had freed was the concrete crash; the symbol map readers (CDisasm::Show/NotifyMapLoaded, CtrlModuleList, CtrlWatchList) had the same shape. Always g_frameMutex first, then Memory::Lock(). Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01GZq8ZtJmFY7bkX5FVkr3P9
This commit is contained in:
1 parent
4a10fa2808
commit
f57a102027
4 files changed
+11
-2
No files matched your search
@@ -61,9 +61,10 @@ void CtrlDisAsmView::deinit()
|
||||
void CtrlDisAsmView::scanVisibleFunctions()
|
||||
{
|
||||
// Reads live memory/symbol state to detect function boundaries - hold g_frameMutex for the
|
||||
// duration, which NativeFrame() also holds while it's actually touching that state. See
|
||||
// g_frameMutex in Core.h.
|
||||
// duration, which NativeFrame() also holds while it's actually touching that state, and
|
||||
// Memory::Lock() so the core can't be torn down mid-read. See g_frameMutex in Core.h.
|
||||
std::lock_guard<std::mutex> frameGuard(g_frameMutex);
|
||||
Memory::MemoryInitedLock memLock = Memory::Lock();
|
||||
g_disassemblyManager.analyze(windowStart, g_disassemblyManager.getNthNextAddress(windowStart,visibleRows)-windowStart);
|
||||
}
|
||||
|
||||
|
||||
@@ -203,6 +203,7 @@ void CtrlRegisterList::onPaint(WPARAM wParam, LPARAM lParam)
|
||||
// with the CPU thread - hold g_frameMutex for the duration of the read, which NativeFrame()
|
||||
// also holds while it's actually touching that state. See g_frameMutex in Core.h.
|
||||
std::lock_guard<std::mutex> frameGuard(g_frameMutex);
|
||||
Memory::MemoryInitedLock memLock = Memory::Lock();
|
||||
// The values are a moving target while the core is running - gray them out rather than trying
|
||||
// to highlight "changes" that are really just noise at that point.
|
||||
bool running = !Core_IsStepping();
|
||||
|
||||
@@ -730,6 +730,7 @@ void CDisasm::Show(bool bShow, bool includeToTop) {
|
||||
// thread - hold g_frameMutex for the duration of the read, which NativeFrame() also
|
||||
// holds while it's actually touching that state. See g_frameMutex in Core.h.
|
||||
std::lock_guard<std::mutex> frameGuard(g_frameMutex);
|
||||
Memory::MemoryInitedLock memLock = Memory::Lock();
|
||||
g_symbolMap->FillSymbolListBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST), ST_FUNCTION);
|
||||
deferredSymbolFill_ = false;
|
||||
}
|
||||
@@ -740,6 +741,7 @@ void CDisasm::Show(bool bShow, bool includeToTop) {
|
||||
void CDisasm::NotifyMapLoaded() {
|
||||
if (m_bShowState != SW_HIDE && g_symbolMap) {
|
||||
std::lock_guard<std::mutex> frameGuard(g_frameMutex);
|
||||
Memory::MemoryInitedLock memLock = Memory::Lock();
|
||||
g_symbolMap->FillSymbolListBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST), ST_FUNCTION);
|
||||
} else {
|
||||
deferredSymbolFill_ = true;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "Windows/main.h"
|
||||
#include "Common/Data/Encoding/Utf8.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/MemMap.h"
|
||||
#include "Core/HLE/sceKernelThread.h"
|
||||
|
||||
enum { TL_NAME, TL_PROGRAMCOUNTER, TL_ENTRYPOINT, TL_PRIORITY, TL_STATE, TL_WAITTYPE, TL_COLUMNCOUNT };
|
||||
@@ -260,6 +261,7 @@ void CtrlThreadList::reloadThreads()
|
||||
// while it's actually touching that state. See g_frameMutex in Core.h.
|
||||
{
|
||||
std::lock_guard<std::mutex> frameGuard(g_frameMutex);
|
||||
Memory::MemoryInitedLock memLock = Memory::Lock();
|
||||
threads = GetThreadsInfo();
|
||||
}
|
||||
Update();
|
||||
@@ -335,6 +337,7 @@ void CtrlBreakpointList::reloadBreakpoints()
|
||||
// with the CPU thread - see g_frameMutex in Core.h.
|
||||
{
|
||||
std::lock_guard<std::mutex> frameGuard(g_frameMutex);
|
||||
Memory::MemoryInitedLock memLock = Memory::Lock();
|
||||
displayedBreakPoints_ = g_breakpoints.GetBreakpoints();
|
||||
displayedMemChecks_= g_breakpoints.GetMemChecks();
|
||||
}
|
||||
@@ -845,6 +848,7 @@ void CtrlModuleList::loadModules()
|
||||
// actually touching that state. See g_frameMutex in Core.h.
|
||||
{
|
||||
std::lock_guard<std::mutex> frameGuard(g_frameMutex);
|
||||
Memory::MemoryInitedLock memLock = Memory::Lock();
|
||||
if (g_symbolMap) {
|
||||
modules = g_symbolMap->getAllModules();
|
||||
} else {
|
||||
@@ -870,6 +874,7 @@ void CtrlWatchList::RefreshValues() {
|
||||
// otherwise race with the CPU thread - hold g_frameMutex for the duration, which NativeFrame()
|
||||
// also holds while it's actually touching that state. See g_frameMutex in Core.h.
|
||||
std::lock_guard<std::mutex> frameGuard(g_frameMutex);
|
||||
Memory::MemoryInitedLock memLock = Memory::Lock();
|
||||
|
||||
int steppingCounter = Core_GetSteppingCounter();
|
||||
int changes = false;
|
||||
|
||||
Reference in new issue
Block a user