Debugger: Fixed deadlock when reloading ROM

This commit is contained in:
Sour 2020-05-14 19:34:14 -04:00
parent 6d9dc99814
commit a402a2c569
5 changed files with 34 additions and 6 deletions

View file

@ -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 = _debugger;
if(debugger) {
while(debugger->HasBreakRequest()) {}
}
_threadPaused = false;
_runLock.Acquire();
}
}

View file

@ -78,6 +78,7 @@ private:
atomic<bool> _stopFlag;
atomic<bool> _paused;
atomic<bool> _pauseOnNextFrame;
atomic<bool> _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);

View file

@ -87,7 +87,7 @@ Debugger::Debugger(shared_ptr<Console> console)
_step.reset(new StepRequest());
_executionStopped = false;
_executionStopped = true;
_breakRequestCount = 0;
_suspendRequestCount = 0;
@ -99,6 +99,7 @@ Debugger::Debugger(shared_ptr<Console> 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)

View file

@ -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);

View file

@ -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);