1
0
Fork 0

DBG+GUI: enable/disable hardware breakpoints

This commit is contained in:
Mr. eXoDia 2014-08-02 01:59:03 +02:00
parent f0f6a15244
commit dab3e45508
10 changed files with 141 additions and 24 deletions

View File

@ -150,12 +150,12 @@ bool bpenumall(BPENUMCALLBACK cbEnum)
return bpenumall(cbEnum, 0);
}
int bpgetcount(BP_TYPE type)
int bpgetcount(BP_TYPE type, bool enabledonly)
{
int count=0;
for(BreakpointsInfo::iterator i=breakpoints.begin(); i!=breakpoints.end(); ++i)
{
if(i->first.first==type)
if(i->first.first==type && (!enabledonly || i->second.enabled))
count++;
}
return count;

View File

@ -40,7 +40,7 @@ bool bpenable(uint addr, BP_TYPE type, bool enable);
bool bpsetname(uint addr, BP_TYPE type, const char* name);
bool bpenumall(BPENUMCALLBACK cbEnum);
bool bpenumall(BPENUMCALLBACK cbEnum, const char* module);
int bpgetcount(BP_TYPE type);
int bpgetcount(BP_TYPE type, bool enabledonly = false);
void bptobridge(const BREAKPOINT* bp, BRIDGEBP* bridge);
void bpcachesave(JSON root);
void bpcacheload(JSON root);

View File

@ -536,7 +536,7 @@ static bool cbSetModuleBreakpoints(const BREAKPOINT* bp)
case BPHARDWARE:
{
if(!SetHardwareBreakPoint(bp->addr, (bp->titantype>>8)&0xF, (bp->titantype>>4)&0xF, bp->titantype&0xF, (void*)cbHardwareBreakpoint))
if(!SetHardwareBreakPoint(bp->addr, 0, (bp->titantype>>4)&0xF, bp->titantype&0xF, (void*)cbHardwareBreakpoint))
dprintf("could not set hardware breakpoint "fhex"!\n", bp->addr);
}
break;
@ -1248,7 +1248,7 @@ bool cbEnableAllBreakpoints(const BREAKPOINT* bp)
{
if(!bpenable(bp->addr, BPNORMAL, true) or !SetBPX(bp->addr, bp->titantype, (void*)cbUserBreakpoint))
{
dprintf("could not enable "fhex"\n", bp->addr);
dprintf("could not enable breakpoint "fhex"\n", bp->addr);
return false;
}
return true;
@ -1258,7 +1258,27 @@ bool cbDisableAllBreakpoints(const BREAKPOINT* bp)
{
if(!bpenable(bp->addr, BPNORMAL, false) or !DeleteBPX(bp->addr))
{
dprintf("could not disable "fhex"\n", bp->addr);
dprintf("could not disable breakpoint "fhex"\n", bp->addr);
return false;
}
return true;
}
bool cbEnableAllHardwareBreakpoints(const BREAKPOINT* bp)
{
if(!bpenable(bp->addr, BPHARDWARE, true) or !SetHardwareBreakPoint(bp->addr, (bp->titantype>>8)&0xF, (bp->titantype>>4)&0xF, bp->titantype&0xF, (void*)cbHardwareBreakpoint))
{
dprintf("could not enable hardware breakpoint "fhex"\n", bp->addr);
return false;
}
return true;
}
bool cbDisableAllHardwareBreakpoints(const BREAKPOINT* bp)
{
if(!bpenable(bp->addr, BPHARDWARE, false) or !DeleteHardwareBreakPoint((bp->titantype>>8)&0xF))
{
dprintf("could not disable hardware breakpoint "fhex"\n", bp->addr);
return false;
}
return true;
@ -1300,6 +1320,18 @@ bool cbDeleteAllMemoryBreakpoints(const BREAKPOINT* bp)
return true;
}
bool cbDeleteAllHardwareBreakpoints(const BREAKPOINT* bp)
{
if(!bp->enabled)
return true;
if(!bpdel(bp->addr, BPHARDWARE) or !DeleteHardwareBreakPoint((bp->titantype>>8)&0xF))
{
dprintf("delete hardware breakpoint failed: "fhex"\n", bp->addr);
return STATUS_ERROR;
}
return true;
}
static void cbAttachDebugger()
{
varset("$hp", (uint)fdProcessInfo->hProcess, true);

View File

@ -60,8 +60,11 @@ DWORD WINAPI threadDebugLoop(void* lpParameter);
bool cbDeleteAllBreakpoints(const BREAKPOINT* bp);
bool cbEnableAllBreakpoints(const BREAKPOINT* bp);
bool cbDisableAllBreakpoints(const BREAKPOINT* bp);
bool cbEnableAllHardwareBreakpoints(const BREAKPOINT* bp);
bool cbDisableAllHardwareBreakpoints(const BREAKPOINT* bp);
bool cbBreakpointList(const BREAKPOINT* bp);
bool cbDeleteAllMemoryBreakpoints(const BREAKPOINT* bp);
bool cbDeleteAllHardwareBreakpoints(const BREAKPOINT* bp);
DWORD WINAPI threadAttachLoop(void* lpParameter);
void cbDetach();

View File

@ -280,14 +280,14 @@ CMDRESULT cbDebugDeleteBPX(int argc, char* argv[])
CMDRESULT cbDebugEnableBPX(int argc, char* argv[])
{
char arg1[deflen]="";
if(!argget(*argv, arg1, 0, true)) //delete all breakpoints
if(!argget(*argv, arg1, 0, true)) //enable all breakpoints
{
if(!bpgetcount(BPNORMAL))
{
dputs("no breakpoints to enable!");
return STATUS_CONTINUE;
}
if(!bpenumall(cbEnableAllBreakpoints)) //at least one deletion failed
if(!bpenumall(cbEnableAllBreakpoints)) //at least one enable failed
return STATUS_ERROR;
dputs("all breakpoints enabled!");
GuiUpdateAllViews();
@ -626,7 +626,7 @@ CMDRESULT cbDebugSetHardwareBreakpoint(int argc, char* argv[])
DWORD drx=0;
if(!GetUnusedHardwareBreakPointRegister(&drx))
{
dputs("no free debug register");
dputs("you can only set 4 hardware breakpoints");
return STATUS_ERROR;
}
int titantype=(drx<<8)|(type<<4)|(DWORD)size;
@ -646,18 +646,6 @@ CMDRESULT cbDebugSetHardwareBreakpoint(int argc, char* argv[])
return STATUS_CONTINUE;
}
static bool cbDeleteAllHardwareBreakpoints(const BREAKPOINT* bp)
{
if(!bp->enabled)
return true;
if(!bpdel(bp->addr, BPHARDWARE) or !DeleteHardwareBreakPoint((bp->titantype>>8)&0xF))
{
dprintf("delete hardware breakpoint failed: "fhex"\n", bp->addr);
return STATUS_ERROR;
}
return true;
}
CMDRESULT cbDebugDeleteHardwareBreakpoint(int argc, char* argv[])
{
char arg1[deflen]="";
@ -1147,4 +1135,87 @@ CMDRESULT cbDebugSetPriority(int argc, char* argv[])
return STATUS_ERROR;
GuiUpdateAllViews();
return STATUS_CONTINUE;
}
CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[])
{
char arg1[deflen]="";
DWORD drx=0;
if(!GetUnusedHardwareBreakPointRegister(0))
{
dputs("you can only set 4 hardware breakpoints");
return STATUS_ERROR;
}
if(!argget(*argv, arg1, 0, true)) //enable all hardware breakpoints
{
if(!bpgetcount(BPHARDWARE))
{
dputs("no hardware breakpoints to enable!");
return STATUS_CONTINUE;
}
if(!bpenumall(cbEnableAllHardwareBreakpoints)) //at least one enable failed
return STATUS_ERROR;
dputs("all hardware breakpoints enabled!");
GuiUpdateAllViews();
return STATUS_CONTINUE;
}
BREAKPOINT found;
uint addr=0;
if(!valfromstring(arg1, &addr) or !bpget(addr, BPHARDWARE, 0, &found)) //invalid hardware breakpoint
{
dprintf("no such hardware breakpoint \"%s\"\n", arg1);
return STATUS_ERROR;
}
if(found.enabled)
{
dputs("hardware breakpoint already enabled!");
GuiUpdateAllViews();
return STATUS_CONTINUE;
}
if(!bpenable(found.addr, BPHARDWARE, true) or !SetHardwareBreakPoint(found.addr, 0, (found.titantype>>4)&0xF, found.titantype&0xF, (void*)cbHardwareBreakpoint))
{
dprintf("could not enable "fhex"\n", found.addr);
return STATUS_ERROR;
}
dputs("hardware breakpoint enabled!");
GuiUpdateAllViews();
return STATUS_CONTINUE;
}
CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[])
{
char arg1[deflen]="";
if(!argget(*argv, arg1, 0, true)) //delete all hardware breakpoints
{
if(!bpgetcount(BPNORMAL))
{
dputs("no hardware breakpoints to disable!");
return STATUS_CONTINUE;
}
if(!bpenumall(cbDisableAllHardwareBreakpoints)) //at least one deletion failed
return STATUS_ERROR;
dputs("all hardware breakpoints disabled!");
GuiUpdateAllViews();
return STATUS_CONTINUE;
}
BREAKPOINT found;
uint addr=0;
if(!valfromstring(arg1, &addr) or !bpget(addr, BPHARDWARE, 0, &found)) //invalid hardware breakpoint
{
dprintf("no such hardware breakpoint \"%s\"\n", arg1);
return STATUS_ERROR;
}
if(!found.enabled)
{
dputs("hardware breakpoint already disabled!");
return STATUS_CONTINUE;
}
if(!bpenable(found.addr, BPHARDWARE, false) or !DeleteHardwareBreakPoint((found.titantype>>8)&0xF))
{
dprintf("could not disable "fhex"\n", found.addr);
return STATUS_ERROR;
}
dputs("hardware breakpoint disabled!");
GuiUpdateAllViews();
return STATUS_CONTINUE;
}

View File

@ -46,5 +46,7 @@ CMDRESULT cbDebugResumethread(int argc, char* argv[]);
CMDRESULT cbDebugSuspendthread(int argc, char* argv[]);
CMDRESULT cbDebugKillthread(int argc, char* argv[]);
CMDRESULT cbDebugSetPriority(int argc, char* argv[]);
CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[]);
CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[]);
#endif //_DEBUGGER_COMMANDS_H

View File

@ -112,6 +112,8 @@ static void registercommands()
dbgcmdnew("DisableBPX\1bpd\1bd", cbDebugDisableBPX, true); //breakpoint disable
dbgcmdnew("SetHardwareBreakpoint\1bph\1bphws", cbDebugSetHardwareBreakpoint, true); //hardware breakpoint
dbgcmdnew("DeleteHardwareBreakpoint\1bphc\1bphwc", cbDebugDeleteHardwareBreakpoint, true); //delete hardware breakpoint
dbgcmdnew("EnableHardwareBreakpoint\1bphe\1bphwe", cbDebugEnableHardwareBreakpoint, true); //enable hardware breakpoint
dbgcmdnew("DisableHardwareBreakpoint\1bphd\1bphwd", cbDebugDisableHardwareBreakpoint, true); //disable hardware breakpoint
dbgcmdnew("SetMemoryBPX\1membp\1bpm", cbDebugSetMemoryBpx, true); //SetMemoryBPX
dbgcmdnew("DeleteMemoryBPX\1membpc\1bpmc", cbDebugDeleteMemoryBreakpoint, true); //delete memory breakpoint

View File

@ -404,6 +404,7 @@ void BreakpointsView::setupMemBPRightClickContextMenu()
// Enable/Disable
mMemBPEnableDisableAction = new QAction("Enable", this);
mMemBPEnableDisableAction->setShortcutContext(Qt::WidgetShortcut);
mMemBPEnableDisableAction->setEnabled(false);
mMemBPTable->addAction(mMemBPEnableDisableAction);
connect(mMemBPEnableDisableAction, SIGNAL(triggered()), this, SLOT(enableDisableMemBPActionSlot()));
}

View File

@ -143,7 +143,13 @@ void CPUDisassembly::contextMenuEvent(QContextMenuEvent* event)
BPMAP wBPList;
DbgGetBpList(bp_hardware, &wBPList);
if(wBPList.count < 4)
//get enabled hwbp count
int enabledCount = wBPList.count;
for(int i=0; i<wBPList.count; i++)
if(!wBPList.bp[i].enabled)
enabledCount--;
if(enabledCount < 4)
{
mBPMenu->addAction(mSetHwBpAction);
}

View File

@ -61,7 +61,7 @@ void Breakpoints::enableBP(BRIDGEBP bp)
if(bp.type == bp_hardware)
{
// Todo
wCmd = "bphwe " + QString("%1").arg(bp.addr, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
}
else if(bp.type == bp_normal)
{
@ -119,7 +119,7 @@ void Breakpoints::disableBP(BRIDGEBP bp)
if(bp.type == bp_hardware)
{
// Todo
wCmd = "bphwd " + QString("%1").arg(bp.addr, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
}
else if(bp.type == bp_normal)
{