From a402a2c5695252ab7bdc3fe4e77e39459d531ad7 Mon Sep 17 00:00:00 2001 From: Sour Date: Thu, 14 May 2020 19:34:14 -0400 Subject: [PATCH] Debugger: Fixed deadlock when reloading ROM --- Core/Console.cpp | 24 ++++++++++++++++++++---- Core/Console.h | 2 ++ Core/Debugger.cpp | 10 ++++++++-- Core/Debugger.h | 1 + Core/LabelManager.cpp | 3 +++ 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/Core/Console.cpp b/Core/Console.cpp index 1447e19..65b676f 100644 --- a/Core/Console.cpp +++ b/Core/Console.cpp @@ -49,6 +49,7 @@ Console::Console() _stopFlag = false; _isRunAheadFrame = false; _lockCounter = 0; + _threadPaused = false; } Console::~Console() @@ -144,6 +145,11 @@ void Console::Run() if(_paused && !_stopFlag && !_debugger) { WaitForPauseEnd(); } + + if(_memoryManager->GetMasterClock() == 0) { + //After a reset or power cycle, run the PPU/etc ahead of the CPU (simulates delay CPU takes to get out of reset) + _memoryManager->IncMasterClockStartup(); + } } _movieManager->Stop(); @@ -339,8 +345,6 @@ void Console::Reset() debugger->SuspendDebugger(true); } - _memoryManager->IncMasterClockStartup(); - _runLock.Release(); _lockCounter--; } @@ -357,8 +361,6 @@ void Console::ReloadRom(bool forPowerCycle) RomInfo info = cart->GetRomInfo(); Lock(); LoadRom(info.RomFile, info.PatchFile, false, forPowerCycle); - - _memoryManager->IncMasterClockStartup(); Unlock(); } } @@ -609,15 +611,29 @@ void Console::Unlock() _lockCounter--; } +bool Console::IsThreadPaused() +{ + return !_emuThread || _threadPaused; +} + void Console::WaitForLock() { if(_lockCounter > 0) { //Need to temporarely pause the emu (to save/load a state, etc.) _runLock.Release(); + _threadPaused = true; + //Spin wait until we are allowed to start again while(_lockCounter > 0) {} + shared_ptr debugger = _debugger; + if(debugger) { + while(debugger->HasBreakRequest()) {} + } + + _threadPaused = false; + _runLock.Acquire(); } } diff --git a/Core/Console.h b/Core/Console.h index cb88f07..592b4d3 100644 --- a/Core/Console.h +++ b/Core/Console.h @@ -78,6 +78,7 @@ private: atomic _stopFlag; atomic _paused; atomic _pauseOnNextFrame; + atomic _threadPaused; ConsoleRegion _region; uint32_t _masterClockRate; @@ -130,6 +131,7 @@ public: ConsoleLock AcquireLock(); void Lock(); void Unlock(); + bool IsThreadPaused(); void Serialize(ostream &out, int compressionLevel = 1); void Deserialize(istream &in, uint32_t fileFormatVersion, bool compressed = true); diff --git a/Core/Debugger.cpp b/Core/Debugger.cpp index df898a8..4a7b875 100644 --- a/Core/Debugger.cpp +++ b/Core/Debugger.cpp @@ -87,7 +87,7 @@ Debugger::Debugger(shared_ptr console) _step.reset(new StepRequest()); - _executionStopped = false; + _executionStopped = true; _breakRequestCount = 0; _suspendRequestCount = 0; @@ -99,6 +99,7 @@ Debugger::Debugger(shared_ptr console) if(_console->IsPaused()) { Step(CpuType::Cpu, 1, StepType::Step); } + _executionStopped = false; } Debugger::~Debugger() @@ -378,7 +379,12 @@ void Debugger::Step(CpuType cpuType, int32_t stepCount, StepType type) bool Debugger::IsExecutionStopped() { - return _executionStopped; + return _executionStopped || _console->IsThreadPaused(); +} + +bool Debugger::HasBreakRequest() +{ + return _breakRequestCount > 0; } void Debugger::BreakRequest(bool release) diff --git a/Core/Debugger.h b/Core/Debugger.h index 6ca47fe..e1a6886 100644 --- a/Core/Debugger.h +++ b/Core/Debugger.h @@ -111,6 +111,7 @@ public: void Step(CpuType cpuType, int32_t stepCount, StepType type); bool IsExecutionStopped(); + bool HasBreakRequest(); void BreakRequest(bool release); void SuspendDebugger(bool release); diff --git a/Core/LabelManager.cpp b/Core/LabelManager.cpp index 7f38352..7c624f5 100644 --- a/Core/LabelManager.cpp +++ b/Core/LabelManager.cpp @@ -2,6 +2,7 @@ #include "LabelManager.h" #include "Debugger.h" #include "DebugUtilities.h" +#include "DebugBreakHelper.h" LabelManager::LabelManager(Debugger *debugger) { @@ -10,12 +11,14 @@ LabelManager::LabelManager(Debugger *debugger) void LabelManager::ClearLabels() { + DebugBreakHelper helper(_debugger); _codeLabels.clear(); _codeLabelReverseLookup.clear(); } void LabelManager::SetLabel(uint32_t address, SnesMemoryType memType, string label, string comment) { + DebugBreakHelper helper(_debugger); uint64_t key = GetLabelKey(address, memType); auto existingLabel = _codeLabels.find(key);