Skip to content

Commit

Permalink
WIP: refactor the breakpoint system
Browse files Browse the repository at this point in the history
  • Loading branch information
mrexodia committed Apr 14, 2023
1 parent b833538 commit 26a776c
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 47 deletions.
61 changes: 43 additions & 18 deletions src/dbg/breakpoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,20 @@ static void setBpActive(BREAKPOINT & bp)
return;
}

// Breakpoints without modules need a valid address
if(!*bp.mod)
// If the breakpoint wasn't set by the engine it won't be active
if(!bp.active)
return;

if(bp.mod[0] == '\0')
{
// Breakpoints without modules need a valid address
bp.active = MemIsValidReadPtr(bp.addr);
return;
}
else
{
auto modLoaded = ModBaseFromName(bp.mod) != 0;
if(bp.type == BPHARDWARE)
bp.active = modLoaded;
else
bp.active = modLoaded && MemIsValidReadPtr(bp.addr);
// If the module unloaded the breakpoint is no longer active
bp.active = ModBaseFromName(bp.mod) != 0;
}
}

Expand Down Expand Up @@ -73,7 +74,6 @@ int BpGetList(std::vector<BREAKPOINT>* List)
BREAKPOINT currentBp = i.second;
if(currentBp.type != BPDLL && currentBp.type != BPEXCEPTION)
currentBp.addr += ModBaseFromName(currentBp.mod);
setBpActive(currentBp);

List->push_back(currentBp);
}
Expand Down Expand Up @@ -114,12 +114,20 @@ bool BpNew(duint Address, bool Enable, bool Singleshot, short OldBytes, BP_TYPE
}
strncpy_s(bp.name, Name, _TRUNCATE);

bp.active = true;
if(Type != BPDLL && Type != BPEXCEPTION)
bp.addr = Address - ModBaseFromAddr(Address);
else
if(Type == BPDLL || Type == BPEXCEPTION)
{
// These types of breakpoints are always active
bp.active = true;
bp.addr = Address;
}
else
{
bp.addr = Address - ModBaseFromAddr(Address);
}
bp.enabled = Enable;
// TODO: a little hacky
if(Enable)
bp.active = true;
bp.oldbytes = OldBytes;
bp.singleshoot = Singleshot;
bp.titantype = TitanType;
Expand Down Expand Up @@ -184,7 +192,6 @@ bool BpGet(duint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
*Bp = *bpInfo;
if(bpInfo->type != BPDLL && bpInfo->type != BPEXCEPTION)
Bp->addr += ModBaseFromAddr(Address);
setBpActive(*Bp);
return true;
}

Expand Down Expand Up @@ -230,7 +237,6 @@ bool BpGet(duint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp)

*Bp = *bpInfo;
Bp->addr = Address;
setBpActive(*Bp);
return true;
}
free(DLLName);
Expand All @@ -251,7 +257,6 @@ bool BpGet(duint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
*Bp = i.second;
if(i.second.type != BPDLL && i.second.type != BPEXCEPTION)
Bp->addr += ModBaseFromAddr(Address);
setBpActive(*Bp);
}

// Return true if the name was found at all
Expand Down Expand Up @@ -365,6 +370,7 @@ bool BpEnable(duint Address, BP_TYPE Type, bool Enable)
return false;

bpInfo->enabled = Enable;
bpInfo->active = Enable;

//Re-read oldbytes
if(Enable && Type == BPNORMAL)
Expand Down Expand Up @@ -409,6 +415,20 @@ bool BpSetTitanType(duint Address, BP_TYPE Type, int TitanType)
return true;
}

bool BpSetActive(duint Address, BP_TYPE Type, bool Active)
{
ASSERT_DEBUGGING("Command function call");
EXCLUSIVE_ACQUIRE(LockBreakpoints);

BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address);

if(!bpInfo)
return false;

bpInfo->active = Active;
return true;
}

bool BpSetBreakCondition(duint Address, BP_TYPE Type, const char* Condition)
{
ASSERT_DEBUGGING("Command function call");
Expand Down Expand Up @@ -578,12 +598,17 @@ bool BpEnumAll(BPENUMCALLBACK EnumCallback, const char* Module, duint base)
BREAKPOINT bpInfo = j->second;
if(bpInfo.type != BPDLL && bpInfo.type != BPEXCEPTION)
{
if(base) //workaround for some Windows bullshit with compatibility mode
if(base) //workaround for some Windows bullshit with compatibility mode
bpInfo.addr += base;
else
bpInfo.addr += ModBaseFromName(bpInfo.mod);
{
char arg[deflen];
sprintf_s(arg, "%s:$%X", bpInfo.mod, bpInfo.addr);
BREAKPOINT found;
if(BpGet(0, bpInfo.type, arg, &found)) //found a breakpoint with name
bpInfo = found;
}
}
setBpActive(bpInfo);

// Lock must be released due to callback sub-locks
SHARED_RELEASE();
Expand Down
3 changes: 2 additions & 1 deletion src/dbg/breakpoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct BREAKPOINT
duint addr; // address of the breakpoint (rva relative to base of mod)
bool enabled; // whether the breakpoint is enabled
bool singleshoot; // whether the breakpoint should be deleted on first hit
bool active; // whether the breakpoint is active or not
bool active; // whether the breakpoint is active (enabled + actually set) or not
bool silent; // whether the breakpoint diplays a default message when hit
unsigned short oldbytes; // original bytes (for software breakpoitns)
BP_TYPE type; // breakpoint type
Expand Down Expand Up @@ -56,6 +56,7 @@ bool BpDelete(duint Address, BP_TYPE Type);
bool BpEnable(duint Address, BP_TYPE Type, bool Enable);
bool BpSetName(duint Address, BP_TYPE Type, const char* Name);
bool BpSetTitanType(duint Address, BP_TYPE Type, int TitanType);
bool BpSetActive(duint Address, BP_TYPE Type, bool Active);
bool BpSetBreakCondition(duint Address, BP_TYPE Type, const char* Condition);
bool BpSetLogText(duint Address, BP_TYPE Type, const char* Log);
bool BpSetLogCondition(duint Address, BP_TYPE Type, const char* Condition);
Expand Down
52 changes: 26 additions & 26 deletions src/dbg/commands/cmd-breakpoint-control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ static bool cbDeleteAllBreakpoints(const BREAKPOINT* bp)
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete breakpoint failed (BpDelete): %p\n"), bp->addr);
return false;
}
if(bp->enabled && !DeleteBPX(bp->addr))
if(bp->active && !DeleteBPX(bp->addr))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete breakpoint failed (DeleteBPX): %p\n"), bp->addr);
return false;
Expand Down Expand Up @@ -53,7 +53,7 @@ static bool cbDisableAllBreakpoints(const BREAKPOINT* bp)
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable breakpoint %p (BpEnable)\n"), bp->addr);
return false;
}
if(!DeleteBPX(bp->addr))
if(bp->active && !DeleteBPX(bp->addr))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable breakpoint %p (DeleteBPX)\n"), bp->addr);
return false;
Expand Down Expand Up @@ -192,7 +192,7 @@ bool cbDebugDeleteBPX(int argc, char* argv[])
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete breakpoint failed (bpdel): %p\n"), found.addr);
return false;
}
if(found.enabled && !DeleteBPX(found.addr))
if(found.active && !DeleteBPX(found.addr))
{
GuiUpdateAllViews();
if(!MemIsValidReadPtr(found.addr))
Expand Down Expand Up @@ -286,7 +286,7 @@ bool cbDebugDisableBPX(int argc, char* argv[])
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable breakpoint %p (BpEnable)\n"), found.addr);
return false;
}
if(!DeleteBPX(found.addr))
if(found.active && !DeleteBPX(found.addr))
{
GuiUpdateAllViews();
if(!MemIsValidReadPtr(found.addr))
Expand All @@ -313,7 +313,7 @@ bool cbDebugDisableBPX(int argc, char* argv[])
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable breakpoint %p (BpEnable)\n"), found.addr);
return false;
}
if(!DeleteBPX(found.addr))
if(found.active && !DeleteBPX(found.addr))
{
GuiUpdateAllViews();
if(!MemIsValidReadPtr(found.addr))
Expand Down Expand Up @@ -357,14 +357,14 @@ static bool cbEnableAllHardwareBreakpoints(const BREAKPOINT* bp)
int titantype = bp->titantype;
TITANSETDRX(titantype, drx);
BpSetTitanType(bp->addr, BPHARDWARE, titantype);
if(!BpEnable(bp->addr, BPHARDWARE, true))
if(!SetHardwareBreakPoint(bp->addr, drx, TITANGETTYPE(bp->titantype), TITANGETSIZE(bp->titantype), cbHardwareBreakpoint))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable hardware breakpoint %p (BpEnable)\n"), bp->addr);
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable hardware breakpoint %p (SetHardwareBreakPoint)\n"), bp->addr);
return false;
}
if(!SetHardwareBreakPoint(bp->addr, drx, TITANGETTYPE(bp->titantype), TITANGETSIZE(bp->titantype), cbHardwareBreakpoint))
if(!BpEnable(bp->addr, BPHARDWARE, true))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable hardware breakpoint %p (SetHardwareBreakPoint)\n"), bp->addr);
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable hardware breakpoint %p (BpEnable)\n"), bp->addr);
return false;
}
return true;
Expand Down Expand Up @@ -641,7 +641,7 @@ static bool cbDeleteAllMemoryBreakpoints(const BREAKPOINT* bp)
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed (BpDelete): %p\n"), bp->addr);
return false;
}
if(bp->enabled && !RemoveMemoryBPX(bp->addr, size))
if(bp->active && !RemoveMemoryBPX(bp->addr, size))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed (RemoveMemoryBPX): %p\n"), bp->addr);
return false;
Expand All @@ -655,14 +655,14 @@ static bool cbEnableAllMemoryBreakpoints(const BREAKPOINT* bp)
return true;
duint size = 0;
MemFindBaseAddr(bp->addr, &size);
if(!BpEnable(bp->addr, BPMEMORY, true))
if(!SetMemoryBPXEx(bp->addr, size, bp->titantype, !bp->singleshoot, cbMemoryBreakpoint))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable memory breakpoint %p (BpEnable)\n"), bp->addr);
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable memory breakpoint %p (SetMemoryBPXEx)\n"), bp->addr);
return false;
}
if(!SetMemoryBPXEx(bp->addr, size, bp->titantype, !bp->singleshoot, cbMemoryBreakpoint))
if(!BpEnable(bp->addr, BPMEMORY, true))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable memory breakpoint %p (SetMemoryBPXEx)\n"), bp->addr);
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable memory breakpoint %p (BpEnable)\n"), bp->addr);
return false;
}
return true;
Expand All @@ -677,7 +677,7 @@ static bool cbDisableAllMemoryBreakpoints(const BREAKPOINT* bp)
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable memory breakpoint %p (BpEnable)\n"), bp->addr);
return false;
}
if(!RemoveMemoryBPX(bp->addr, 0))
if(bp->active && !RemoveMemoryBPX(bp->addr, 0))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable memory breakpoint %p (RemoveMemoryBPX)\n"), bp->addr);
return false;
Expand Down Expand Up @@ -780,7 +780,7 @@ bool cbDebugDeleteMemoryBreakpoint(int argc, char* argv[])
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed: %p (BpDelete)\n"), found.addr);
return false;
}
if(!RemoveMemoryBPX(found.addr, size))
if(found.active && !RemoveMemoryBPX(found.addr, size))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed: %p (RemoveMemoryBPX)\n"), found.addr);
return false;
Expand All @@ -801,7 +801,7 @@ bool cbDebugDeleteMemoryBreakpoint(int argc, char* argv[])
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed: %p (BpDelete)\n"), found.addr);
return false;
}
if(!RemoveMemoryBPX(found.addr, size))
if(found.active && !RemoveMemoryBPX(found.addr, size))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed: %p (RemoveMemoryBPX)\n"), found.addr);
return false;
Expand Down Expand Up @@ -885,7 +885,7 @@ bool cbDebugDisableMemoryBreakpoint(int argc, char* argv[])
}
duint size = 0;
MemFindBaseAddr(found.addr, &size);
if(!RemoveMemoryBPX(found.addr, size))
if(found.active && !RemoveMemoryBPX(found.addr, size))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable memory breakpoint %p (RemoveMemoryBPX)\n"), found.addr);
return false;
Expand Down Expand Up @@ -923,14 +923,14 @@ static bool cbEnableAllDllBreakpoints(const BREAKPOINT* bp)
if(bp->type != BPDLL || bp->enabled)
return true;

if(!BpEnable(bp->addr, BPDLL, true))
if(!dbgsetdllbreakpoint(bp->mod, bp->titantype, bp->singleshoot))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (BpEnable)\n"), bp->mod);
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (LibrarianSetBreakPoint)\n"), bp->mod);
return false;
}
if(!dbgsetdllbreakpoint(bp->mod, bp->titantype, bp->singleshoot))
if(!BpEnable(bp->addr, BPDLL, true))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (LibrarianSetBreakPoint)\n"), bp->mod);
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (BpEnable)\n"), bp->mod);
return false;
}
return true;
Expand Down Expand Up @@ -1059,15 +1059,15 @@ bool cbDebugBpDllEnable(int argc, char* argv[])
dputs(QT_TRANSLATE_NOOP("DBG", "DLL breakpoint already enabled!"));
return true;
}
if(!dbgsetdllbreakpoint(found.mod, found.titantype, found.singleshoot))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (LibrarianSetBreakPoint)\n"), found.mod);
}
if(!BpEnable(found.addr, BPDLL, true))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (BpEnable)\n"), found.mod);
return false;
}
if(!dbgsetdllbreakpoint(found.mod, found.titantype, found.singleshoot))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (LibrarianSetBreakPoint)\n"), found.mod);
}
dputs(QT_TRANSLATE_NOOP("DBG", "DLL breakpoint enable!"));
GuiUpdateAllViews();
return true;
Expand Down
12 changes: 10 additions & 2 deletions src/dbg/debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1098,10 +1098,12 @@ bool cbSetModuleBreakpoints(const BREAKPOINT* bp)
bp->addr,
((unsigned char*)&bp->oldbytes)[0], ((unsigned char*)&bp->oldbytes)[1],
((unsigned char*)&oldbytes)[0], ((unsigned char*)&oldbytes)[1]);
BpEnable(bp->addr, BPNORMAL, false);
BpEnable(bp->addr, bp->type, false);
}
else if(!SetBPX(bp->addr, bp->titantype, cbUserBreakpoint))
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not set breakpoint %p! (SetBPX)\n"), bp->addr);
else
BpSetActive(bp->addr, bp->type, true);
}
else
dprintf(QT_TRANSLATE_NOOP("DBG", "MemRead failed on breakpoint address %p!\n"), bp->addr);
Expand All @@ -1114,6 +1116,8 @@ bool cbSetModuleBreakpoints(const BREAKPOINT* bp)
MemFindBaseAddr(bp->addr, &size);
if(!SetMemoryBPXEx(bp->addr, size, bp->titantype, !bp->singleshoot, cbMemoryBreakpoint))
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not set memory breakpoint %p! (SetMemoryBPXEx)\n"), bp->addr);
else
BpSetActive(bp->addr, bp->type, true);
}
break;

Expand All @@ -1127,11 +1131,14 @@ bool cbSetModuleBreakpoints(const BREAKPOINT* bp)
}
int titantype = bp->titantype;
TITANSETDRX(titantype, drx);
BpSetTitanType(bp->addr, BPHARDWARE, titantype);
BpSetTitanType(bp->addr, bp->type, titantype);
if(!SetHardwareBreakPoint(bp->addr, drx, TITANGETTYPE(bp->titantype), TITANGETSIZE(bp->titantype), cbHardwareBreakpoint))
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not set hardware breakpoint %p! (SetHardwareBreakPoint)\n"), bp->addr);
else
{
BpSetActive(bp->addr, bp->type, true);
dprintf(QT_TRANSLATE_NOOP("DBG", "Set hardware breakpoint on %p!\n"), bp->addr);
}
}
break;

Expand Down Expand Up @@ -1177,6 +1184,7 @@ static bool cbRemoveModuleBreakpoints(const BREAKPOINT* bp)
default:
break;
}
BpSetActive(bp->addr, bp->type, false);
return true;
}

Expand Down

0 comments on commit 26a776c

Please sign in to comment.