Debugger: Make breakpoint actions more generic.

This commit is contained in:
Unknown W. Brackets 2016-08-04 12:02:44 -07:00
parent a0a4d3cd24
commit a9ad0cd471
5 changed files with 47 additions and 54 deletions

View file

@ -39,11 +39,11 @@ MemCheck::MemCheck()
void MemCheck::Log(u32 addr, bool write, int size, u32 pc) void MemCheck::Log(u32 addr, bool write, int size, u32 pc)
{ {
if (result & MEMCHECK_LOG) if (result & BREAK_ACTION_LOG)
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 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());
} }
void MemCheck::Action(u32 addr, bool write, int size, u32 pc) BreakAction MemCheck::Action(u32 addr, bool write, int size, u32 pc)
{ {
int mask = write ? MEMCHECK_WRITE : MEMCHECK_READ; int mask = write ? MEMCHECK_WRITE : MEMCHECK_READ;
if (cond & mask) if (cond & mask)
@ -51,12 +51,16 @@ void MemCheck::Action(u32 addr, bool write, int size, u32 pc)
++numHits; ++numHits;
Log(addr, write, size, pc); Log(addr, write, size, pc);
if (result & MEMCHECK_BREAK) if (result & BREAK_ACTION_PAUSE)
{ {
Core_EnableStepping(true); Core_EnableStepping(true);
host->SetDebugMode(true); host->SetDebugMode(true);
} }
return result;
} }
return BREAK_ACTION_IGNORE;
} }
void MemCheck::JitBefore(u32 addr, bool write, int size, u32 pc) void MemCheck::JitBefore(u32 addr, bool write, int size, u32 pc)
@ -93,7 +97,7 @@ void MemCheck::JitCleanup()
} }
// Resume if it should not have gone to stepping, or if it did not change. // Resume if it should not have gone to stepping, or if it did not change.
if ((!(result & MEMCHECK_BREAK) || !changed) && coreState == CORE_STEPPING) if ((!(result & BREAK_ACTION_PAUSE) || !changed) && coreState == CORE_STEPPING)
{ {
CBreakPoints::SetSkipFirst(lastPC); CBreakPoints::SetSkipFirst(lastPC);
Core_EnableStepping(false); Core_EnableStepping(false);
@ -268,7 +272,7 @@ BreakPointCond *CBreakPoints::GetBreakPointCondition(u32 addr)
return NULL; return NULL;
} }
void CBreakPoints::AddMemCheck(u32 start, u32 end, MemCheckCondition cond, MemCheckResult result) void CBreakPoints::AddMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result)
{ {
// This will ruin any pending memchecks. // This will ruin any pending memchecks.
cleanupMemChecks_.clear(); cleanupMemChecks_.clear();
@ -288,7 +292,7 @@ void CBreakPoints::AddMemCheck(u32 start, u32 end, MemCheckCondition cond, MemCh
else else
{ {
memChecks_[mc].cond = (MemCheckCondition)(memChecks_[mc].cond | cond); memChecks_[mc].cond = (MemCheckCondition)(memChecks_[mc].cond | cond);
memChecks_[mc].result = (MemCheckResult)(memChecks_[mc].result | result); memChecks_[mc].result = (BreakAction)(memChecks_[mc].result | result);
Update(); Update();
} }
} }
@ -306,7 +310,7 @@ void CBreakPoints::RemoveMemCheck(u32 start, u32 end)
} }
} }
void CBreakPoints::ChangeMemCheck(u32 start, u32 end, MemCheckCondition cond, MemCheckResult result) void CBreakPoints::ChangeMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result)
{ {
size_t mc = FindMemCheck(start, end); size_t mc = FindMemCheck(start, end);
if (mc != INVALID_MEMCHECK) if (mc != INVALID_MEMCHECK)
@ -357,14 +361,15 @@ MemCheck *CBreakPoints::GetMemCheck(u32 address, int size)
return 0; return 0;
} }
void CBreakPoints::ExecMemCheck(u32 address, bool write, int size, u32 pc) BreakAction CBreakPoints::ExecMemCheck(u32 address, bool write, int size, u32 pc)
{ {
auto check = GetMemCheck(address, size); auto check = GetMemCheck(address, size);
if (check) if (check)
check->Action(address, write, size, pc); return check->Action(address, write, size, pc);
return BREAK_ACTION_IGNORE;
} }
void CBreakPoints::ExecOpMemCheck(u32 address, u32 pc) BreakAction CBreakPoints::ExecOpMemCheck(u32 address, u32 pc)
{ {
// Note: currently, we don't check "on changed" for HLE (ExecMemCheck.) // Note: currently, we don't check "on changed" for HLE (ExecMemCheck.)
// We'd need to more carefully specify memory changes in HLE for that. // We'd need to more carefully specify memory changes in HLE for that.
@ -381,12 +386,13 @@ void CBreakPoints::ExecOpMemCheck(u32 address, u32 pc)
int mask = MEMCHECK_WRITE | MEMCHECK_WRITE_ONCHANGE; int mask = MEMCHECK_WRITE | MEMCHECK_WRITE_ONCHANGE;
if (write && (check->cond & mask) == mask) { if (write && (check->cond & mask) == mask) {
if (MIPSAnalyst::OpWouldChangeMemory(pc, address, size)) { if (MIPSAnalyst::OpWouldChangeMemory(pc, address, size)) {
check->Action(address, write, size, pc); return check->Action(address, write, size, pc);
} }
} else { } else {
check->Action(address, write, size, pc); return check->Action(address, write, size, pc);
} }
} }
return BREAK_ACTION_IGNORE;
} }
void CBreakPoints::ExecMemCheckJitBefore(u32 address, bool write, int size, u32 pc) void CBreakPoints::ExecMemCheckJitBefore(u32 address, bool write, int size, u32 pc)

View file

@ -21,6 +21,15 @@
#include "Core/Debugger/DebugInterface.h" #include "Core/Debugger/DebugInterface.h"
enum BreakAction
{
BREAK_ACTION_IGNORE = 0x00,
BREAK_ACTION_LOG = 0x01,
BREAK_ACTION_PAUSE = 0x02,
BREAK_ACTION_BOTH = 0x03,
};
struct BreakPointCond struct BreakPointCond
{ {
DebugInterface *debug; DebugInterface *debug;
@ -68,14 +77,7 @@ enum MemCheckCondition
MEMCHECK_READWRITE = 0x03, MEMCHECK_READWRITE = 0x03,
}; };
enum MemCheckResult
{
MEMCHECK_IGNORE = 0x00,
MEMCHECK_LOG = 0x01,
MEMCHECK_BREAK = 0x02,
MEMCHECK_BOTH = 0x03,
};
struct MemCheck struct MemCheck
{ {
@ -84,7 +86,7 @@ struct MemCheck
u32 end; u32 end;
MemCheckCondition cond; MemCheckCondition cond;
MemCheckResult result; BreakAction result;
u32 numHits; u32 numHits;
@ -92,7 +94,7 @@ struct MemCheck
u32 lastAddr; u32 lastAddr;
int lastSize; int lastSize;
void Action(u32 addr, bool write, int size, u32 pc); BreakAction Action(u32 addr, bool write, int size, u32 pc);
void JitBefore(u32 addr, bool write, int size, u32 pc); void JitBefore(u32 addr, bool write, int size, u32 pc);
void JitCleanup(); void JitCleanup();
@ -127,14 +129,14 @@ public:
static void ChangeBreakPointRemoveCond(u32 addr); static void ChangeBreakPointRemoveCond(u32 addr);
static BreakPointCond *GetBreakPointCondition(u32 addr); static BreakPointCond *GetBreakPointCondition(u32 addr);
static void AddMemCheck(u32 start, u32 end, MemCheckCondition cond, MemCheckResult result); static void AddMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result);
static void RemoveMemCheck(u32 start, u32 end); static void RemoveMemCheck(u32 start, u32 end);
static void ChangeMemCheck(u32 start, u32 end, MemCheckCondition cond, MemCheckResult result); static void ChangeMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result);
static void ClearAllMemChecks(); static void ClearAllMemChecks();
static MemCheck *GetMemCheck(u32 address, int size); static MemCheck *GetMemCheck(u32 address, int size);
static void ExecMemCheck(u32 address, bool write, int size, u32 pc); static BreakAction ExecMemCheck(u32 address, bool write, int size, u32 pc);
static void ExecOpMemCheck(u32 address, u32 pc); static BreakAction ExecOpMemCheck(u32 address, u32 pc);
// Executes memchecks but used by the jit. Cleanup finalizes after jit is done. // Executes memchecks but used by the jit. Cleanup finalizes after jit is done.
static void ExecMemCheckJitBefore(u32 address, bool write, int size, u32 pc); static void ExecMemCheckJitBefore(u32 address, bool write, int size, u32 pc);

View file

@ -194,13 +194,13 @@ void BreakpointWindow::addBreakpoint()
if (onChange) if (onChange)
cond |= MEMCHECK_WRITE_ONCHANGE; cond |= MEMCHECK_WRITE_ONCHANGE;
MemCheckResult result; int result = BREAK_ACTION_IGNORE;
if (log && enabled) result = MEMCHECK_BOTH; if (log)
else if (log) result = MEMCHECK_LOG; result |= BREAK_ACTION_LOG;
else if (enabled) result = MEMCHECK_BREAK; if (enabled)
else result = MEMCHECK_IGNORE; result |= BREAK_ACTION_PAUSE;
CBreakPoints::AddMemCheck(address, address + size, (MemCheckCondition)cond, result); CBreakPoints::AddMemCheck(address, address + size, (MemCheckCondition)cond, (BreakAction)result);
} else { } else {
// add breakpoint // add breakpoint
CBreakPoints::AddBreakPoint(address,false); CBreakPoints::AddBreakPoint(address,false);
@ -229,23 +229,8 @@ void BreakpointWindow::loadFromMemcheck(MemCheck& memcheck)
write = (memcheck.cond & MEMCHECK_WRITE) != 0; write = (memcheck.cond & MEMCHECK_WRITE) != 0;
onChange = (memcheck.cond & MEMCHECK_WRITE_ONCHANGE) != 0; onChange = (memcheck.cond & MEMCHECK_WRITE_ONCHANGE) != 0;
switch (memcheck.result) log = (memcheck.result & BREAK_ACTION_LOG) != 0;
{ enabled = (memcheck.result & BREAK_ACTION_PAUSE) != 0;
case MEMCHECK_BOTH:
log = enabled = true;
break;
case MEMCHECK_LOG:
log = true;
enabled = false;
break;
case MEMCHECK_BREAK:
log = false;
enabled = true;
break;
case MEMCHECK_IGNORE:
log = enabled = false;
break;
}
address = memcheck.start; address = memcheck.start;
size = memcheck.end-address; size = memcheck.end-address;

View file

@ -324,7 +324,7 @@ void CtrlBreakpointList::reloadBreakpoints()
continue; continue;
if (isMemory) if (isMemory)
SetCheckState(i,(displayedMemChecks_[index].result & MEMCHECK_BREAK) != 0); SetCheckState(i, (displayedMemChecks_[index].result & BREAK_ACTION_PAUSE) != 0);
else else
SetCheckState(i, displayedBreakPoints_[index].enabled); SetCheckState(i, displayedBreakPoints_[index].enabled);
} }
@ -365,7 +365,7 @@ void CtrlBreakpointList::toggleEnabled(int itemIndex)
if (isMemory) { if (isMemory) {
MemCheck mcPrev = displayedMemChecks_[index]; MemCheck mcPrev = displayedMemChecks_[index];
CBreakPoints::ChangeMemCheck(mcPrev.start, mcPrev.end, mcPrev.cond, MemCheckResult(mcPrev.result ^ MEMCHECK_BREAK)); CBreakPoints::ChangeMemCheck(mcPrev.start, mcPrev.end, mcPrev.cond, BreakAction(mcPrev.result ^ BREAK_ACTION_PAUSE));
} else { } else {
BreakPoint bpPrev = displayedBreakPoints_[index]; BreakPoint bpPrev = displayedBreakPoints_[index];
CBreakPoints::ChangeBreakPoint(bpPrev.addr, !bpPrev.enabled); CBreakPoints::ChangeBreakPoint(bpPrev.addr, !bpPrev.enabled);
@ -605,7 +605,7 @@ void CtrlBreakpointList::showBreakpointMenu(int itemIndex, const POINT &pt)
HMENU subMenu = GetSubMenu(g_hPopupMenus, POPUP_SUBMENU_ID_BREAKPOINTLIST); HMENU subMenu = GetSubMenu(g_hPopupMenus, POPUP_SUBMENU_ID_BREAKPOINTLIST);
if (isMemory) { if (isMemory) {
CheckMenuItem(subMenu, ID_DISASM_DISABLEBREAKPOINT, MF_BYCOMMAND | (mcPrev.result & MEMCHECK_BREAK ? MF_CHECKED : MF_UNCHECKED)); CheckMenuItem(subMenu, ID_DISASM_DISABLEBREAKPOINT, MF_BYCOMMAND | (mcPrev.result & BREAK_ACTION_PAUSE ? MF_CHECKED : MF_UNCHECKED));
} else { } else {
CheckMenuItem(subMenu, ID_DISASM_DISABLEBREAKPOINT, MF_BYCOMMAND | (bpPrev.enabled ? MF_CHECKED : MF_UNCHECKED)); CheckMenuItem(subMenu, ID_DISASM_DISABLEBREAKPOINT, MF_BYCOMMAND | (bpPrev.enabled ? MF_CHECKED : MF_UNCHECKED));
} }
@ -614,7 +614,7 @@ void CtrlBreakpointList::showBreakpointMenu(int itemIndex, const POINT &pt)
{ {
case ID_DISASM_DISABLEBREAKPOINT: case ID_DISASM_DISABLEBREAKPOINT:
if (isMemory) { if (isMemory) {
CBreakPoints::ChangeMemCheck(mcPrev.start, mcPrev.end, mcPrev.cond, MemCheckResult(mcPrev.result ^ MEMCHECK_BREAK)); CBreakPoints::ChangeMemCheck(mcPrev.start, mcPrev.end, mcPrev.cond, BreakAction(mcPrev.result ^ BREAK_ACTION_PAUSE));
} else { } else {
CBreakPoints::ChangeBreakPoint(bpPrev.addr, !bpPrev.enabled); CBreakPoints::ChangeBreakPoint(bpPrev.addr, !bpPrev.enabled);
} }

View file

@ -282,7 +282,7 @@ BEGIN
CONTROL "On change",IDC_BREAKPOINT_ONCHANGE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,170,34,50,10 CONTROL "On change",IDC_BREAKPOINT_ONCHANGE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,170,34,50,10
LTEXT "Condition",IDC_STATIC,7,51,31,8 LTEXT "Condition",IDC_STATIC,7,51,31,8
EDITTEXT IDC_BREAKPOINT_CONDITION,41,49,187,14,ES_AUTOHSCROLL EDITTEXT IDC_BREAKPOINT_CONDITION,41,49,187,14,ES_AUTOHSCROLL
CONTROL "Enabled",IDC_BREAKPOINT_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,41,71,41,10 CONTROL "Break",IDC_BREAKPOINT_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,41,71,41,10
CONTROL "Log",IDC_BREAKPOINT_LOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,96,71,27,10 CONTROL "Log",IDC_BREAKPOINT_LOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,96,71,27,10
DEFPUSHBUTTON "OK",IDC_BREAKPOINT_OK,144,68,41,14 DEFPUSHBUTTON "OK",IDC_BREAKPOINT_OK,144,68,41,14
PUSHBUTTON "Cancel",IDC_BREAKPOINT_CANCEL,186,68,42,14 PUSHBUTTON "Cancel",IDC_BREAKPOINT_CANCEL,186,68,42,14