Skip to content

Commit

Permalink
Merge pull request #14056 from unknownbrackets/debugger-mem
Browse files Browse the repository at this point in the history
Track memory allocations and writes for debug info
  • Loading branch information
hrydgard committed Feb 21, 2021
2 parents ea07493 + ee71ef9 commit 2f3bc2d
Show file tree
Hide file tree
Showing 55 changed files with 1,044 additions and 360 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Expand Up @@ -1485,6 +1485,8 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/Debugger/Breakpoints.cpp
Core/Debugger/Breakpoints.h
Core/Debugger/DebugInterface.h
Core/Debugger/MemBlockInfo.cpp
Core/Debugger/MemBlockInfo.h
Core/Debugger/SymbolMap.cpp
Core/Debugger/SymbolMap.h
Core/Debugger/DisassemblyManager.cpp
Expand Down
2 changes: 2 additions & 0 deletions Core/Core.vcxproj
Expand Up @@ -429,6 +429,7 @@
<ClCompile Include="..\ext\udis86\syn.c" />
<ClCompile Include="..\ext\udis86\udis86.c" />
<ClCompile Include="AVIDump.cpp" />
<ClCompile Include="Debugger\MemBlockInfo.cpp" />
<ClCompile Include="Debugger\WebSocket.cpp" />
<ClCompile Include="Debugger\WebSocket\BreakpointSubscriber.cpp" />
<ClCompile Include="Debugger\WebSocket\CPUCoreSubscriber.cpp" />
Expand Down Expand Up @@ -977,6 +978,7 @@
<ClInclude Include="..\ext\udis86\udis86.h" />
<ClInclude Include="AVIDump.h" />
<ClInclude Include="ConfigValues.h" />
<ClInclude Include="Debugger\MemBlockInfo.h" />
<ClInclude Include="Debugger\WebSocket.h" />
<ClInclude Include="Debugger\WebSocket\BreakpointSubscriber.h" />
<ClInclude Include="Debugger\WebSocket\GameSubscriber.h" />
Expand Down
6 changes: 6 additions & 0 deletions Core/Core.vcxproj.filters
Expand Up @@ -977,6 +977,9 @@
<ClCompile Include="MIPS\fake\FakeJit.cpp">
<Filter>MIPS\fake</Filter>
</ClCompile>
<ClCompile Include="Debugger\MemBlockInfo.cpp">
<Filter>Debugger</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ELF\ElfReader.h">
Expand Down Expand Up @@ -1670,6 +1673,9 @@
<ClInclude Include="MIPS\fake\FakeJit.h">
<Filter>MIPS\fake</Filter>
</ClInclude>
<ClInclude Include="Debugger\MemBlockInfo.h">
<Filter>Debugger</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />
Expand Down
5 changes: 3 additions & 2 deletions Core/CwCheat.cpp
Expand Up @@ -11,6 +11,7 @@
#include "Core/CwCheat.h"
#include "Core/Config.h"
#include "Core/Host.h"
#include "Core/MemMapHelpers.h"
#include "Core/MIPS/MIPS.h"
#include "Core/ELF/ParamSFO.h"
#include "Core/System.h"
Expand Down Expand Up @@ -924,7 +925,7 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat,
InvalidateICache(op.addr, op.val);
InvalidateICache(op.copyBytesFrom.destAddr, op.val);

Memory::MemcpyUnchecked(op.copyBytesFrom.destAddr, op.addr, op.val);
Memory::Memcpy(op.copyBytesFrom.destAddr, op.addr, op.val, "CwCheat");
}
break;

Expand Down Expand Up @@ -1106,7 +1107,7 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat,
if (Memory::IsValidRange(dstAddr, val) && Memory::IsValidRange(srcAddr, val)) {
InvalidateICache(dstAddr, val);
InvalidateICache(srcAddr, val);
Memory::MemcpyUnchecked(dstAddr, srcAddr, val);
Memory::Memcpy(dstAddr, srcAddr, val, "CwCheat");
}
// Don't perform any further action.
type = -1;
Expand Down
21 changes: 11 additions & 10 deletions Core/Debugger/Breakpoints.cpp
Expand Up @@ -40,14 +40,15 @@ static std::mutex memCheckMutex_;
std::vector<MemCheck> CBreakPoints::memChecks_;
std::vector<MemCheck *> CBreakPoints::cleanupMemChecks_;

void MemCheck::Log(u32 addr, bool write, int size, u32 pc) {
void MemCheck::Log(u32 addr, bool write, int size, u32 pc, const char *reason) {
if (result & BREAK_ACTION_LOG) {
const char *type = write ? "Write" : "Read";
if (logFormat.empty()) {
NOTICE_LOG(MEMMAP, "CHK %s%i at %08x (%s), PC=%08x (%s)", write ? "Write" : "Read", size * 8, addr, g_symbolMap->GetDescription(addr).c_str(), pc, g_symbolMap->GetDescription(pc).c_str());
NOTICE_LOG(MEMMAP, "CHK %s%i(%s) at %08x (%s), PC=%08x (%s)", type, size * 8, reason, addr, g_symbolMap->GetDescription(addr).c_str(), pc, g_symbolMap->GetDescription(pc).c_str());
} else {
std::string formatted;
CBreakPoints::EvaluateLogFormat(currentDebugMIPS, logFormat, formatted);
NOTICE_LOG(MEMMAP, "CHK %s%i at %08x: %s", write ? "Write" : "Read", size * 8, addr, formatted.c_str());
NOTICE_LOG(MEMMAP, "CHK %s%i(%s) at %08x: %s", type, size * 8, reason, addr, formatted.c_str());
}
}
}
Expand All @@ -62,10 +63,10 @@ BreakAction MemCheck::Apply(u32 addr, bool write, int size, u32 pc) {
return BREAK_ACTION_IGNORE;
}

BreakAction MemCheck::Action(u32 addr, bool write, int size, u32 pc) {
BreakAction MemCheck::Action(u32 addr, bool write, int size, u32 pc, const char *reason) {
int mask = write ? MEMCHECK_WRITE : MEMCHECK_READ;
if (cond & mask) {
Log(addr, write, size, pc);
Log(addr, write, size, pc, reason);
if ((result & BREAK_ACTION_PAUSE) && coreState != CORE_POWERUP) {
Core_EnableStepping(true);
host->SetDebugMode(true);
Expand Down Expand Up @@ -94,7 +95,7 @@ void MemCheck::JitBeforeAction(u32 addr, bool write, int size, u32 pc) {
// We have to break to find out if it changed.
Core_EnableStepping(true);
} else {
Action(addr, write, size, pc);
Action(addr, write, size, pc, "CPU");
}
}

Expand All @@ -116,7 +117,7 @@ void MemCheck::JitCleanup(bool changed)
return;

if (changed)
Log(lastAddr, true, lastSize, lastPC);
Log(lastAddr, true, lastSize, lastPC, "CPU");

// Resume if it should not have gone to stepping, or if it did not change.
if ((!(result & BREAK_ACTION_PAUSE) || !changed) && coreState == CORE_STEPPING)
Expand Down Expand Up @@ -504,7 +505,7 @@ MemCheck *CBreakPoints::GetMemCheckLocked(u32 address, int size) {
return 0;
}

BreakAction CBreakPoints::ExecMemCheck(u32 address, bool write, int size, u32 pc)
BreakAction CBreakPoints::ExecMemCheck(u32 address, bool write, int size, u32 pc, const char *reason)
{
if (!anyMemChecks_)
return BREAK_ACTION_IGNORE;
Expand All @@ -514,7 +515,7 @@ BreakAction CBreakPoints::ExecMemCheck(u32 address, bool write, int size, u32 pc
check->Apply(address, write, size, pc);
auto copy = *check;
guard.unlock();
return copy.Action(address, write, size, pc);
return copy.Action(address, write, size, pc, reason);
}
return BREAK_ACTION_IGNORE;
}
Expand Down Expand Up @@ -547,7 +548,7 @@ BreakAction CBreakPoints::ExecOpMemCheck(u32 address, u32 pc)
check->Apply(address, write, size, pc);
auto copy = *check;
guard.unlock();
return copy.Action(address, write, size, pc);
return copy.Action(address, write, size, pc, "CPU");
}
}
return BREAK_ACTION_IGNORE;
Expand Down
6 changes: 3 additions & 3 deletions Core/Debugger/Breakpoints.h
Expand Up @@ -96,13 +96,13 @@ struct MemCheck {
// Called on the stored memcheck (affects numHits, etc.)
BreakAction Apply(u32 addr, bool write, int size, u32 pc);
// Called on a copy.
BreakAction Action(u32 addr, bool write, int size, u32 pc);
BreakAction Action(u32 addr, bool write, int size, u32 pc, const char *reason);
void JitBeforeApply(u32 addr, bool write, int size, u32 pc);
void JitBeforeAction(u32 addr, bool write, int size, u32 pc);
bool JitApplyChanged();
void JitCleanup(bool changed);

void Log(u32 addr, bool write, int size, u32 pc);
void Log(u32 addr, bool write, int size, u32 pc, const char *reason);

bool IsEnabled() const {
return (result & BREAK_ACTION_PAUSE) != 0;
Expand Down Expand Up @@ -151,7 +151,7 @@ class CBreakPoints

static bool GetMemCheck(u32 start, u32 end, MemCheck *check);
static bool GetMemCheckInRange(u32 address, int size, MemCheck *check);
static BreakAction ExecMemCheck(u32 address, bool write, int size, u32 pc);
static BreakAction ExecMemCheck(u32 address, bool write, int size, u32 pc, const char *reason);
static BreakAction ExecOpMemCheck(u32 address, u32 pc);

// Executes memchecks but used by the jit. Cleanup finalizes after jit is done.
Expand Down

0 comments on commit 2f3bc2d

Please sign in to comment.