DLL breakpoint GUI (#1048)
* New Splitter Widget * DLL breakpoint interface * Conditional DLL Breakpoint * maintain translation file * Don't animate when it stops * fixed some issues * DLL Breakpoint GUI * DLL Breakpoint GUI * Fixed DLL Path problem * When not debugging, the user can use "run" button to restart. * further fixes
This commit is contained in:
parent
9b703ae9b2
commit
4e2636416c
|
@ -231,6 +231,10 @@ static bool _getbridgebp(BPXTYPE type, duint addr, BRIDGEBP* bp)
|
|||
case bp_memory:
|
||||
bptype = BPMEMORY;
|
||||
break;
|
||||
case bp_dll:
|
||||
bptype = BPDLL;
|
||||
addr = ModHashFromName(reinterpret_cast<const char*>(addr));
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -116,11 +116,12 @@ bool BpNewDll(const char* module, bool Enable, bool Singleshot, DWORD TitanType,
|
|||
bp.singleshoot = Singleshot;
|
||||
bp.titantype = TitanType;
|
||||
bp.type = BPDLL;
|
||||
bp.addr = BpGetDLLBpAddr(module);
|
||||
|
||||
// Insert new entry to the global list
|
||||
EXCLUSIVE_ACQUIRE(LockBreakpoints);
|
||||
|
||||
return breakpoints.insert(std::make_pair(BreakpointKey(BPDLL, ModHashFromName(bp.mod)), bp)).second;
|
||||
return breakpoints.insert(std::make_pair(BreakpointKey(BPDLL, bp.addr), bp)).second;
|
||||
}
|
||||
|
||||
bool BpGet(duint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
|
||||
|
@ -174,10 +175,10 @@ bool BpGet(duint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
|
|||
|
||||
bool BpGetAny(BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
|
||||
{
|
||||
if(BpGet(0, Type, Name, Bp))
|
||||
return true;
|
||||
if(Type != BPDLL)
|
||||
{
|
||||
if(BpGet(0, Type, Name, Bp))
|
||||
return true;
|
||||
duint addr;
|
||||
if(valfromstring(Name, &addr))
|
||||
if(BpGet(addr, Type, 0, Bp))
|
||||
|
@ -185,7 +186,7 @@ bool BpGetAny(BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
|
|||
}
|
||||
else
|
||||
{
|
||||
if(BpGet(ModHashFromName(Name), Type, Name, Bp))
|
||||
if(BpGet(BpGetDLLBpAddr(Name), Type, 0, Bp))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -201,8 +202,13 @@ bool BpUpdateDllPath(const char* module1, BREAKPOINT** newBpInfo)
|
|||
{
|
||||
if(_stricmp(i.second.mod, module1) == 0)
|
||||
{
|
||||
strcpy_s(i.second.mod, module1);
|
||||
*newBpInfo = &i.second;
|
||||
BREAKPOINT temp;
|
||||
temp = i.second;
|
||||
strcpy_s(temp.mod, module1);
|
||||
temp.addr = ModHashFromName(module1);
|
||||
breakpoints.erase(i.first);
|
||||
auto newItem = breakpoints.insert(std::make_pair(BreakpointKey(BPDLL, temp.addr), temp));
|
||||
*newBpInfo = &newItem.first->second;
|
||||
return true;
|
||||
}
|
||||
const char* dashPos = max(strrchr(i.second.mod, '\\'), strrchr(i.second.mod, '/'));
|
||||
|
@ -212,8 +218,13 @@ bool BpUpdateDllPath(const char* module1, BREAKPOINT** newBpInfo)
|
|||
dashPos += 1;
|
||||
if(dashPos1 != nullptr && _stricmp(dashPos, dashPos1 + 1) == 0) // filename matches
|
||||
{
|
||||
strcpy_s(i.second.mod, module1);
|
||||
*newBpInfo = &i.second;
|
||||
BREAKPOINT temp;
|
||||
temp = i.second;
|
||||
strcpy_s(temp.mod, dashPos1 + 1);
|
||||
temp.addr = ModHashFromName(dashPos1 + 1);
|
||||
breakpoints.erase(i.first);
|
||||
auto newItem = breakpoints.insert(std::make_pair(BreakpointKey(BPDLL, temp.addr), temp));
|
||||
*newBpInfo = &newItem.first->second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -222,6 +233,16 @@ bool BpUpdateDllPath(const char* module1, BREAKPOINT** newBpInfo)
|
|||
return false;
|
||||
}
|
||||
|
||||
duint BpGetDLLBpAddr(const char* fileName)
|
||||
{
|
||||
const char* dashPos1 = max(strrchr(fileName, '\\'), strrchr(fileName, '/'));
|
||||
if(dashPos1 == nullptr)
|
||||
dashPos1 = fileName;
|
||||
else
|
||||
dashPos1++;
|
||||
return ModHashFromName(dashPos1);
|
||||
}
|
||||
|
||||
bool BpDelete(duint Address, BP_TYPE Type)
|
||||
{
|
||||
ASSERT_DEBUGGING("Command function call");
|
||||
|
@ -589,9 +610,9 @@ void BpCacheSave(JSON Root)
|
|||
const JSON jsonBreakpoints = json_array();
|
||||
|
||||
// Loop all breakpoints
|
||||
for(auto & i : breakpoints)
|
||||
for(const auto & i : breakpoints)
|
||||
{
|
||||
auto & breakpoint = i.second;
|
||||
const auto & breakpoint = i.second;
|
||||
|
||||
// Ignore single-shot breakpoints
|
||||
if(breakpoint.singleshoot)
|
||||
|
@ -676,7 +697,15 @@ void BpCacheLoad(JSON Root)
|
|||
breakpoint.silent = json_boolean_value(json_object_get(value, "silent"));
|
||||
|
||||
// Build the hash map key: MOD_HASH + ADDRESS
|
||||
duint key = ModHashFromName(breakpoint.mod) + breakpoint.addr;
|
||||
duint key;
|
||||
if(breakpoint.type != BPDLL)
|
||||
{
|
||||
key = ModHashFromName(breakpoint.mod) + breakpoint.addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
key = BpGetDLLBpAddr(breakpoint.mod);
|
||||
}
|
||||
breakpoints.insert(std::make_pair(BreakpointKey(breakpoint.type, key), breakpoint));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ bool BpSetFastResume(duint Address, BP_TYPE Type, bool fastResume);
|
|||
bool BpSetSingleshoot(duint Address, BP_TYPE Type, bool singleshoot);
|
||||
bool BpEnumAll(BPENUMCALLBACK EnumCallback, const char* Module, duint base = 0);
|
||||
bool BpSetSilent(duint Address, BP_TYPE Type, bool silent);
|
||||
duint BpGetDLLBpAddr(const char* fileName);
|
||||
bool BpEnumAll(BPENUMCALLBACK EnumCallback);
|
||||
int BpGetCount(BP_TYPE Type, bool EnabledOnly = false);
|
||||
uint32 BpGetHitCount(duint Address, BP_TYPE Type);
|
||||
|
|
|
@ -4,6 +4,262 @@
|
|||
#include "memory.h"
|
||||
#include "variable.h"
|
||||
|
||||
// breakpoint enumeration callbacks
|
||||
static bool cbDeleteAllBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPNORMAL)
|
||||
return true;
|
||||
if(!BpDelete(bp->addr, BPNORMAL))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete breakpoint failed (BpDelete): %p\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(bp->enabled && !DeleteBPX(bp->addr))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete breakpoint failed (DeleteBPX): %p\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cbEnableAllBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPNORMAL || bp->enabled)
|
||||
return true;
|
||||
|
||||
if(!SetBPX(bp->addr, bp->titantype, (void*)cbUserBreakpoint))
|
||||
{
|
||||
if(!MemIsValidReadPtr(bp->addr))
|
||||
return true;
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable breakpoint %p (SetBPX)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(!BpEnable(bp->addr, BPNORMAL, true))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cbDisableAllBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPNORMAL || !bp->enabled)
|
||||
return true;
|
||||
|
||||
if(!BpEnable(bp->addr, BPNORMAL, false))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(!DeleteBPX(bp->addr))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable breakpoint %p (DeleteBPX)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cbEnableAllHardwareBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPHARDWARE || bp->enabled)
|
||||
return true;
|
||||
DWORD drx = 0;
|
||||
if(!GetUnusedHardwareBreakPointRegister(&drx))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Did not enable hardware breakpoint %p (all slots full)\n"), bp->addr);
|
||||
return true;
|
||||
}
|
||||
int titantype = bp->titantype;
|
||||
TITANSETDRX(titantype, drx);
|
||||
BpSetTitanType(bp->addr, BPHARDWARE, titantype);
|
||||
if(!BpEnable(bp->addr, BPHARDWARE, true))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable hardware breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(!SetHardwareBreakPoint(bp->addr, drx, TITANGETTYPE(bp->titantype), TITANGETSIZE(bp->titantype), (void*)cbHardwareBreakpoint))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable hardware breakpoint %p (SetHardwareBreakPoint)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cbDisableAllHardwareBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPHARDWARE)
|
||||
return true;
|
||||
if(!BpEnable(bp->addr, BPHARDWARE, false))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable hardware breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(bp->enabled && !DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype)))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable hardware breakpoint %p (DeleteHardwareBreakPoint)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cbEnableAllMemoryBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPMEMORY || bp->enabled)
|
||||
return true;
|
||||
duint size = 0;
|
||||
MemFindBaseAddr(bp->addr, &size);
|
||||
if(!BpEnable(bp->addr, BPMEMORY, true))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable memory breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(!SetMemoryBPXEx(bp->addr, size, bp->titantype, !bp->singleshoot, (void*)cbMemoryBreakpoint))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable memory breakpoint %p (SetMemoryBPXEx)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cbDisableAllMemoryBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPMEMORY || !bp->enabled)
|
||||
return true;
|
||||
if(!BpEnable(bp->addr, BPMEMORY, false))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable memory breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(!RemoveMemoryBPX(bp->addr, 0))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable memory breakpoint %p (RemoveMemoryBPX)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cbEnableAllDllBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPDLL || bp->enabled)
|
||||
return true;
|
||||
|
||||
if(!BpEnable(bp->addr, BPDLL, true))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (BpEnable)\n"), bp->mod);
|
||||
return false;
|
||||
}
|
||||
if(!LibrarianSetBreakPoint(bp->mod, bp->titantype, bp->singleshoot, (void*)cbLibrarianBreakpoint))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (LibrarianSetBreakPoint)\n"), bp->mod);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cbDisableAllDllBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPDLL || !bp->enabled)
|
||||
return true;
|
||||
|
||||
if(!BpEnable(bp->addr, BPDLL, false))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable DLL breakpoint %s (BpEnable)\n"), bp->mod);
|
||||
return false;
|
||||
}
|
||||
if(!LibrarianRemoveBreakPoint(bp->mod, bp->titantype))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable DLL breakpoint %s (LibrarianRemoveBreakPoint)\n"), bp->mod);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cbDeleteAllDllBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPDLL || !bp->enabled)
|
||||
return true;
|
||||
if(!BpDelete(bp->addr, BPDLL))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not delete DLL breakpoint %s (BpDelete)\n"), bp->mod);
|
||||
return false;
|
||||
}
|
||||
if(!LibrarianRemoveBreakPoint(bp->mod, bp->titantype))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not delete DLL breakpoint %s (LibrarianRemoveBreakPoint)\n"), bp->mod);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cbBreakpointList(const BREAKPOINT* bp)
|
||||
{
|
||||
const char* type = 0;
|
||||
if(bp->type == BPNORMAL)
|
||||
{
|
||||
if(bp->singleshoot)
|
||||
type = "SS";
|
||||
else
|
||||
type = "BP";
|
||||
}
|
||||
else if(bp->type == BPHARDWARE)
|
||||
type = "HW";
|
||||
else if(bp->type == BPMEMORY)
|
||||
type = "GP";
|
||||
else if(bp->type == BPDLL)
|
||||
type = "DLL";
|
||||
bool enabled = bp->enabled;
|
||||
if(bp->type == BPDLL)
|
||||
{
|
||||
if(*bp->name)
|
||||
dprintf_untranslated("%d:%s:\"%s\":\"%s\"\n", enabled, type, bp->mod, bp->name);
|
||||
else
|
||||
dprintf_untranslated("%d:%s:\"%s\"\n", enabled, type, bp->mod);
|
||||
}
|
||||
else if(*bp->name)
|
||||
dprintf_untranslated("%d:%s:%p:\"%s\"\n", enabled, type, bp->addr, bp->name);
|
||||
else
|
||||
dprintf_untranslated("%d:%s:%p\n", enabled, type, bp->addr);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cbDeleteAllMemoryBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPMEMORY)
|
||||
return true;
|
||||
duint size;
|
||||
MemFindBaseAddr(bp->addr, &size);
|
||||
if(!BpDelete(bp->addr, BPMEMORY))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed (BpDelete): %p\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(bp->enabled && !RemoveMemoryBPX(bp->addr, size))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed (RemoveMemoryBPX): %p\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cbDeleteAllHardwareBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPHARDWARE)
|
||||
return true;
|
||||
if(!BpDelete(bp->addr, BPHARDWARE))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete hardware breakpoint failed (BpDelete): %p\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(bp->enabled && !DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype)))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete hardware breakpoint failed (DeleteHardwareBreakPoint): %p\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// command callbacks
|
||||
CMDRESULT cbDebugSetBPXOptions(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
|
@ -314,7 +570,7 @@ static CMDRESULT cbDebugSetBPXTextCommon(BP_TYPE Type, int argc, char* argv[], c
|
|||
dputs(QT_TRANSLATE_NOOP("DBG", "not enough arguments!\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
auto value = "";
|
||||
char* value = "";
|
||||
if(argc > 2)
|
||||
value = argv[2];
|
||||
|
||||
|
@ -399,7 +655,7 @@ static CMDRESULT cbDebugResetBPXHitCountCommon(BP_TYPE Type, int argc, char* arg
|
|||
}
|
||||
if(!BpResetHitCount(bp.addr, Type, (uint32)value))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set hit count on breakpoint \"%s\""), argv[1]);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set hit count on breakpoint \"%s\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
DebugUpdateBreakpointsViewAsync();
|
||||
|
@ -429,7 +685,7 @@ static CMDRESULT cbDebugSetBPXFastResumeCommon(BP_TYPE Type, int argc, char* arg
|
|||
}
|
||||
if(!BpSetFastResume(bp.addr, Type, fastResume))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set fast resume on breakpoint \"%1\""), argv[1]);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set fast resume on breakpoint \"%1\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
DebugUpdateBreakpointsViewAsync();
|
||||
|
@ -459,7 +715,7 @@ static CMDRESULT cbDebugSetBPXSingleshootCommon(BP_TYPE Type, int argc, char* ar
|
|||
}
|
||||
if(!BpSetSingleshoot(bp.addr, Type, singleshoot))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set singleshoot on breakpoint \"%1\""), argv[1]);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set singleshoot on breakpoint \"%1\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
DebugUpdateBreakpointsViewAsync();
|
||||
|
@ -489,7 +745,7 @@ static CMDRESULT cbDebugSetBPXSilentCommon(BP_TYPE Type, int argc, char* argv[])
|
|||
}
|
||||
if(!BpSetSilent(bp.addr, Type, silent))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set silent on breakpoint \"%1\""), argv[1]);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set silent on breakpoint \"%1\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
DebugUpdateBreakpointsViewAsync();
|
||||
|
@ -1140,7 +1396,7 @@ CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[])
|
|||
|
||||
CMDRESULT cbDebugDisableMemoryBreakpoint(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2) //delete all memory breakpoints
|
||||
if(argc < 2) //disable all memory breakpoints
|
||||
{
|
||||
if(!BpGetCount(BPMEMORY))
|
||||
{
|
||||
|
@ -1225,13 +1481,18 @@ CMDRESULT cbDebugBpDll(int argc, char* argv[])
|
|||
bool singleshoot = true;
|
||||
if(argc > 3)
|
||||
singleshoot = false;
|
||||
if(!BpNewDll(argv[1], true, true, type, ""))
|
||||
if(!BpNewDll(argv[1], true, false, type, ""))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error creating Dll breakpoint! (BpNewDll)"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!LibrarianSetBreakPoint(argv[1], type, singleshoot, (void*)cbLibrarianBreakpoint))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error creating Dll breakpoint! (LibrarianSetBreakPoint)"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Dll breakpoint set on \"%s\"!\n"), argv[1]);
|
||||
DebugUpdateBreakpointsViewAsync();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
|
@ -1239,18 +1500,114 @@ CMDRESULT cbDebugBcDll(int argc, char* argv[])
|
|||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Not enough arguments"));
|
||||
return STATUS_ERROR;
|
||||
// delete all Dll breakpoints
|
||||
if(!BpGetCount(BPDLL))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "No DLL breakpoints to delete!"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpEnumAll(cbDeleteAllDllBreakpoints)) //at least one deletion failed
|
||||
return STATUS_ERROR;
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "All DLL breakpoints deleted!"));
|
||||
DebugUpdateBreakpointsViewAsync();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpDelete(ModHashFromName(argv[1]), BPDLL))
|
||||
BREAKPOINT bp;
|
||||
if(!BpGetAny(BPDLL, argv[1], &bp))
|
||||
return STATUS_ERROR;
|
||||
if(!BpDelete(bp.addr, BPDLL))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Failed to remove DLL breakpoint..."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!LibrarianRemoveBreakPoint(argv[1], UE_ON_LIB_ALL))
|
||||
if(!LibrarianRemoveBreakPoint(bp.mod, bp.titantype))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Failed to remove DLL breakpoint..."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "DLL breakpoint removed!"));
|
||||
DebugUpdateBreakpointsViewAsync();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugBpDllDisable(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2) //disable all DLL breakpoints
|
||||
{
|
||||
if(!BpGetCount(BPDLL))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "No DLL breakpoints to disable!"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpEnumAll(cbDisableAllDllBreakpoints)) //at least one deletion failed
|
||||
return STATUS_ERROR;
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "All DLL breakpoints disabled!"));
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
BREAKPOINT found;
|
||||
duint addr = 0;
|
||||
if(!BpGetAny(BPDLL, argv[1], &found)) //invalid DLL breakpoint
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "No such DLL breakpoint \"%s\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!found.enabled)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "DLL breakpoint already disabled!"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpEnable(found.addr, BPDLL, false))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable DLL breakpoint %s (BpEnable)\n"), found.mod);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!LibrarianSetBreakPoint(found.mod, found.titantype, found.singleshoot, (void*)cbLibrarianBreakpoint))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable DLL breakpoint %s (LibrarianSetBreakPoint)\n"), found.mod);
|
||||
}
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "DLL breakpoint disabled!"));
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugBpDllEnable(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2) //disable all DLL breakpoints
|
||||
{
|
||||
if(!BpGetCount(BPDLL))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "No DLL breakpoints to enable!"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpEnumAll(cbEnableAllDllBreakpoints)) //at least one deletion failed
|
||||
return STATUS_ERROR;
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "All DLL breakpoints enabled!"));
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
BREAKPOINT found;
|
||||
duint addr = 0;
|
||||
if(!BpGetAny(BPDLL, argv[1], &found)) //invalid DLL breakpoint
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "No such DLL breakpoint \"%s\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(found.enabled)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "DLL breakpoint already enabled!"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpEnable(found.addr, BPDLL, true))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (BpEnable)\n"), found.mod);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!LibrarianRemoveBreakPoint(found.mod, found.titantype))
|
||||
{
|
||||
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 STATUS_CONTINUE;
|
||||
}
|
|
@ -592,9 +592,9 @@ static void printDllBpInfo(const BREAKPOINT & bp)
|
|||
bptype = _strdup("");
|
||||
}
|
||||
if(*bp.name)
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "DLL Breakpoint %s(%s):Module %s"), bp.name, bptype, bp.mod);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "DLL Breakpoint %s(%s):Module %s\n"), bp.name, bptype, bp.mod);
|
||||
else
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "DLL Breakpoint(%s):Module %s"), bptype, bp.mod);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "DLL Breakpoint(%s):Module %s\n"), bptype, bp.mod);
|
||||
free(bptype);
|
||||
}
|
||||
|
||||
|
@ -687,7 +687,7 @@ static void cbGenericBreakpoint(BP_TYPE bptype, void* ExceptionAddress = nullptr
|
|||
bpPtr = BpInfoFromAddr(bptype, MemFindBaseAddr(duint(ExceptionAddress), nullptr, true));
|
||||
break;
|
||||
case BPDLL:
|
||||
bpPtr = BpInfoFromAddr(BPDLL, ModHashFromName(reinterpret_cast<const char*>(ExceptionAddress)));
|
||||
bpPtr = BpInfoFromAddr(BPDLL, BpGetDLLBpAddr(reinterpret_cast<const char*>(ExceptionAddress)));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -965,6 +965,17 @@ bool cbSetModuleBreakpoints(const BREAKPOINT* bp)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool cbSetDLLBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(!bp->enabled)
|
||||
return true;
|
||||
if(bp->type != BPDLL)
|
||||
return true;
|
||||
dputs("debug:dll breakpoint in database\n");
|
||||
LibrarianSetBreakPoint(bp->mod, bp->titantype, bp->singleshoot, (void*)cbLibrarianBreakpoint);
|
||||
return true;
|
||||
}
|
||||
|
||||
EXCEPTION_DEBUG_INFO getLastExceptionInfo()
|
||||
{
|
||||
return lastExceptionInfo;
|
||||
|
@ -1181,6 +1192,7 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
|
|||
char modname[256] = "";
|
||||
if(ModNameFromAddr((duint)base, modname, true))
|
||||
BpEnumAll(cbSetModuleBreakpoints, modname, duint(base));
|
||||
BpEnumAll(cbSetDLLBreakpoints);
|
||||
BpEnumAll(cbSetModuleBreakpoints, "");
|
||||
GuiUpdateBreakpointsView();
|
||||
pCreateProcessBase = (duint)CreateProcessInfo->lpBaseOfImage;
|
||||
|
@ -1755,207 +1767,6 @@ static void cbDebugEvent(DEBUG_EVENT* DebugEvent)
|
|||
plugincbcall(CB_DEBUGEVENT, &debugEventInfo);
|
||||
}
|
||||
|
||||
bool cbDeleteAllBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPNORMAL)
|
||||
return true;
|
||||
if(!BpDelete(bp->addr, BPNORMAL))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete breakpoint failed (BpDelete): %p\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(bp->enabled && !DeleteBPX(bp->addr))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete breakpoint failed (DeleteBPX): %p\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cbEnableAllBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPNORMAL || bp->enabled)
|
||||
return true;
|
||||
|
||||
if(!SetBPX(bp->addr, bp->titantype, (void*)cbUserBreakpoint))
|
||||
{
|
||||
if(!MemIsValidReadPtr(bp->addr))
|
||||
return true;
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable breakpoint %p (SetBPX)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(!BpEnable(bp->addr, BPNORMAL, true))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cbDisableAllBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPNORMAL || !bp->enabled)
|
||||
return true;
|
||||
|
||||
if(!BpEnable(bp->addr, BPNORMAL, false))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(!DeleteBPX(bp->addr))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable breakpoint %p (DeleteBPX)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cbEnableAllHardwareBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPHARDWARE || bp->enabled)
|
||||
return true;
|
||||
DWORD drx = 0;
|
||||
if(!GetUnusedHardwareBreakPointRegister(&drx))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Did not enable hardware breakpoint %p (all slots full)\n"), bp->addr);
|
||||
return true;
|
||||
}
|
||||
int titantype = bp->titantype;
|
||||
TITANSETDRX(titantype, drx);
|
||||
BpSetTitanType(bp->addr, BPHARDWARE, titantype);
|
||||
if(!BpEnable(bp->addr, BPHARDWARE, true))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable hardware breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(!SetHardwareBreakPoint(bp->addr, drx, TITANGETTYPE(bp->titantype), TITANGETSIZE(bp->titantype), (void*)cbHardwareBreakpoint))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable hardware breakpoint %p (SetHardwareBreakPoint)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cbDisableAllHardwareBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPHARDWARE)
|
||||
return true;
|
||||
if(!BpEnable(bp->addr, BPHARDWARE, false))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable hardware breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(bp->enabled && !DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype)))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable hardware breakpoint %p (DeleteHardwareBreakPoint)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cbEnableAllMemoryBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPMEMORY || bp->enabled)
|
||||
return true;
|
||||
duint size = 0;
|
||||
MemFindBaseAddr(bp->addr, &size);
|
||||
if(!BpEnable(bp->addr, BPMEMORY, true))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable memory breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(!SetMemoryBPXEx(bp->addr, size, bp->titantype, !bp->singleshoot, (void*)cbMemoryBreakpoint))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable memory breakpoint %p (SetMemoryBPXEx)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cbDisableAllMemoryBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPMEMORY || !bp->enabled)
|
||||
return true;
|
||||
if(!BpEnable(bp->addr, BPMEMORY, false))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable memory breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(!RemoveMemoryBPX(bp->addr, 0))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable memory breakpoint %p (RemoveMemoryBPX)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cbBreakpointList(const BREAKPOINT* bp)
|
||||
{
|
||||
const char* type = 0;
|
||||
if(bp->type == BPNORMAL)
|
||||
{
|
||||
if(bp->singleshoot)
|
||||
type = "SS";
|
||||
else
|
||||
type = "BP";
|
||||
}
|
||||
else if(bp->type == BPHARDWARE)
|
||||
type = "HW";
|
||||
else if(bp->type == BPMEMORY)
|
||||
type = "GP";
|
||||
else if(bp->type == BPDLL)
|
||||
type = "DLL";
|
||||
bool enabled = bp->enabled;
|
||||
if(bp->type == BPDLL)
|
||||
{
|
||||
if(*bp->name)
|
||||
dprintf_untranslated("%d:%s:\"%s\":\"%s\"\n", enabled, type, bp->mod, bp->name);
|
||||
else
|
||||
dprintf_untranslated("%d:%s:\"%s\"\n", enabled, type, bp->mod);
|
||||
}
|
||||
else if(*bp->name)
|
||||
dprintf_untranslated("%d:%s:%p:\"%s\"\n", enabled, type, bp->addr, bp->name);
|
||||
else
|
||||
dprintf_untranslated("%d:%s:%p\n", enabled, type, bp->addr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cbDeleteAllMemoryBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPMEMORY)
|
||||
return true;
|
||||
duint size;
|
||||
MemFindBaseAddr(bp->addr, &size);
|
||||
if(!BpDelete(bp->addr, BPMEMORY))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed (BpDelete): %p\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(bp->enabled && !RemoveMemoryBPX(bp->addr, size))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed (RemoveMemoryBPX): %p\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cbDeleteAllHardwareBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(bp->type != BPHARDWARE)
|
||||
return true;
|
||||
if(!BpDelete(bp->addr, BPHARDWARE))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete hardware breakpoint failed (BpDelete): %p\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(bp->enabled && !DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype)))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete hardware breakpoint failed (DeleteHardwareBreakPoint): %p\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void cbAttachDebugger()
|
||||
{
|
||||
if(hEvent) //Signal the AeDebug event
|
||||
|
|
|
@ -121,16 +121,6 @@ void cbUserBreakpoint();
|
|||
void cbDebugLoadLibBPX();
|
||||
void cbLibrarianBreakpoint(void* lpData);
|
||||
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 cbEnableAllMemoryBreakpoints(const BREAKPOINT* bp);
|
||||
bool cbDisableAllMemoryBreakpoints(const BREAKPOINT* bp);
|
||||
bool cbBreakpointList(const BREAKPOINT* bp);
|
||||
bool cbDeleteAllMemoryBreakpoints(const BREAKPOINT* bp);
|
||||
bool cbDeleteAllHardwareBreakpoints(const BREAKPOINT* bp);
|
||||
void cbTOCNDStep();
|
||||
void cbTICNDStep();
|
||||
void cbTIBTStep();
|
||||
|
|
|
@ -69,6 +69,8 @@ CMDRESULT cbDebugSetBPXDLLFastResume(int argc, char* argv[]);
|
|||
CMDRESULT cbDebugSetBPXDLLSingleshoot(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXDLLSilent(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugResetBPXDLLHitCount(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugBpDllDisable(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugBpDllEnable(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugBplist(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugStepInto(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugeStepInto(int argc, char* argv[]);
|
||||
|
|
|
@ -138,6 +138,8 @@ static void registercommands()
|
|||
dbgcmdnew("DisableMemoryBreakpoint\1membpd\1bpmd", cbDebugDisableMemoryBreakpoint, true); //enable memory breakpoint
|
||||
dbgcmdnew("LibrarianSetBreakPoint\1bpdll", cbDebugBpDll, true); //set dll breakpoint
|
||||
dbgcmdnew("LibrarianRemoveBreakPoint\1bcdll", cbDebugBcDll, true); //remove dll breakpoint
|
||||
dbgcmdnew("LibrarianDisableBreakPoint", cbDebugBpDllDisable, true);
|
||||
dbgcmdnew("LibrarianEnableBreakPoint", cbDebugBpDllEnable, true);
|
||||
|
||||
//breakpoints (conditional)
|
||||
dbgcmdnew("SetBreakpointName\1bpname", cbDebugSetBPXName, true); //set breakpoint name
|
||||
|
@ -174,16 +176,16 @@ static void registercommands()
|
|||
dbgcmdnew("SetMemoryGetBreakpointHitCount", cbDebugGetBPXMemoryHitCount, true); //get breakpoint hit count
|
||||
dbgcmdnew("ResetMemoryBreakpointHitCount", cbDebugResetBPXMemoryHitCount, true); //reset breakpoint hit count
|
||||
dbgcmdnew("SetLibrarianBreakpointName", cbDebugSetBPXDLLName, true); //set breakpoint name
|
||||
dbgcmdnew("SetLibrarianBreakpointCondition", cbDebugSetBPXMemoryCondition, true); //set breakpoint breakCondition
|
||||
dbgcmdnew("SetLibrarianBreakpointLog", cbDebugSetBPXMemoryLog, true); //set breakpoint log
|
||||
dbgcmdnew("SetLibrarianBreakpointLogCondition", cbDebugSetBPXMemoryLogCondition, true); //set breakpoint logCondition
|
||||
dbgcmdnew("SetLibrarianBreakpointCommand", cbDebugSetBPXMemoryCommand, true); //set breakpoint command on hit
|
||||
dbgcmdnew("SetLibrarianBreakpointCommandCondition", cbDebugSetBPXMemoryCommandCondition, true); //set breakpoint commandCondition
|
||||
dbgcmdnew("SetLibrarianBreakpointFastResume", cbDebugSetBPXMemoryFastResume, true); //set breakpoint fast resume
|
||||
dbgcmdnew("SetLibrarianBreakpointSingleshoot", cbDebugSetBPXMemorySingleshoot, true); //set breakpoint singleshoot
|
||||
dbgcmdnew("SetLibrarianBreakpointSilent", cbDebugSetBPXMemorySilent, true); //set breakpoint fast resume
|
||||
dbgcmdnew("SetLibrarianGetBreakpointHitCount", cbDebugGetBPXMemoryHitCount, true); //get breakpoint hit count
|
||||
dbgcmdnew("ResetLibrarianBreakpointHitCount", cbDebugResetBPXMemoryHitCount, true); //reset breakpoint hit count
|
||||
dbgcmdnew("SetLibrarianBreakpointCondition", cbDebugSetBPXDLLCondition, true); //set breakpoint breakCondition
|
||||
dbgcmdnew("SetLibrarianBreakpointLog", cbDebugSetBPXDLLLog, true); //set breakpoint log
|
||||
dbgcmdnew("SetLibrarianBreakpointLogCondition", cbDebugSetBPXDLLLogCondition, true); //set breakpoint logCondition
|
||||
dbgcmdnew("SetLibrarianBreakpointCommand", cbDebugSetBPXDLLCommand, true); //set breakpoint command on hit
|
||||
dbgcmdnew("SetLibrarianBreakpointCommandCondition", cbDebugSetBPXDLLCommandCondition, true); //set breakpoint commandCondition
|
||||
dbgcmdnew("SetLibrarianBreakpointFastResume", cbDebugSetBPXDLLFastResume, true); //set breakpoint fast resume
|
||||
dbgcmdnew("SetLibrarianBreakpointSingleshoot", cbDebugSetBPXDLLSingleshoot, true); //set breakpoint singleshoot
|
||||
dbgcmdnew("SetLibrarianBreakpointSilent", cbDebugSetBPXDLLSilent, true); //set breakpoint fast resume
|
||||
dbgcmdnew("SetLibrarianGetBreakpointHitCount", cbDebugGetBPXDLLHitCount, true); //get breakpoint hit count
|
||||
dbgcmdnew("ResetLibrarianBreakpointHitCount", cbDebugResetBPXDLLHitCount, true); //reset breakpoint hit count
|
||||
|
||||
dbgcmdnew("bpgoto", cbDebugSetBPGoto, true);
|
||||
|
||||
|
|
|
@ -55,11 +55,25 @@ BreakpointsView::BreakpointsView(QWidget* parent) : QWidget(parent)
|
|||
mMemBPTable->addColumnAt(wCharWidth * 10, tr("Comment"), false);
|
||||
mMemBPTable->loadColumnFromConfig("MemoryBreakpoint");
|
||||
|
||||
// DLL
|
||||
mDLLBPTable = new StdTable(this);
|
||||
mDLLBPTable->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
mDLLBPTable->addColumnAt(8 + wCharWidth * 32, tr("Name"), false);
|
||||
mDLLBPTable->addColumnAt(8 + wCharWidth * 32, tr("Module"), false);
|
||||
mDLLBPTable->addColumnAt(8 + wCharWidth * 8, tr("State"), false);
|
||||
mDLLBPTable->addColumnAt(8 + wCharWidth * 10, tr("Hit count"), false);
|
||||
mDLLBPTable->addColumnAt(8 + wCharWidth * 32, tr("Log text"), false);
|
||||
mDLLBPTable->addColumnAt(8 + wCharWidth * 32, tr("Condition"), false);
|
||||
mDLLBPTable->addColumnAt(8 + wCharWidth * 2, tr("Fast resume"), false);
|
||||
mDLLBPTable->addColumnAt(8 + wCharWidth * 16, tr("Command on hit"), false);
|
||||
mDLLBPTable->loadColumnFromConfig("DLLBreakpoint");
|
||||
|
||||
// Splitter
|
||||
mSplitter = new LabeledSplitter(this);
|
||||
mSplitter->addWidget(mSoftBPTable, tr("Software breakpoint"));
|
||||
mSplitter->addWidget(mHardBPTable, tr("Hardware breakpoint"));
|
||||
mSplitter->addWidget(mMemBPTable, tr("Memory breakpoint"));
|
||||
mSplitter->addWidget(mDLLBPTable, tr("DLL breakpoint"));
|
||||
mSplitter->collapseLowerTabs();
|
||||
|
||||
// Layout
|
||||
|
@ -89,6 +103,9 @@ BreakpointsView::BreakpointsView(QWidget* parent) : QWidget(parent)
|
|||
connect(mMemBPTable, SIGNAL(doubleClickedSignal()), this, SLOT(doubleClickMemorySlot()));
|
||||
connect(mMemBPTable, SIGNAL(enterPressedSignal()), this, SLOT(doubleClickMemorySlot()));
|
||||
connect(mMemBPTable, SIGNAL(selectionChangedSignal(int)), this, SLOT(selectionChangedMemorySlot()));
|
||||
connect(mDLLBPTable, SIGNAL(contextMenuSignal(const QPoint &)), this, SLOT(DLLBPContextMenuSlot(const QPoint &)));
|
||||
connect(mDLLBPTable, SIGNAL(selectionChangedSignal(int)), this, SLOT(selectionChangedDLLSlot()));
|
||||
|
||||
|
||||
mCurrentType = bp_normal;
|
||||
}
|
||||
|
@ -105,14 +122,14 @@ void BreakpointsView::reloadData()
|
|||
{
|
||||
QString addr_text = QString("%1").arg(wBPList.bp[wI].addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
|
||||
mHardBPTable->setCellContent(wI, 0, addr_text);
|
||||
mHardBPTable->setCellContent(wI, 1, QString(wBPList.bp[wI].name));
|
||||
mHardBPTable->setCellContent(wI, 1, QString::fromUtf8(wBPList.bp[wI].name));
|
||||
|
||||
QString label_text;
|
||||
char label[MAX_LABEL_SIZE] = "";
|
||||
if(DbgGetLabelAt(wBPList.bp[wI].addr, SEG_DEFAULT, label))
|
||||
label_text = "<" + QString(wBPList.bp[wI].mod) + "." + QString(label) + ">";
|
||||
label_text = "<" + QString::fromUtf8(wBPList.bp[wI].mod) + "." + QString::fromUtf8(label) + ">";
|
||||
else
|
||||
label_text = QString(wBPList.bp[wI].mod);
|
||||
label_text = QString::fromUtf8(wBPList.bp[wI].mod);
|
||||
mHardBPTable->setCellContent(wI, 2, label_text);
|
||||
|
||||
if(wBPList.bp[wI].active == false)
|
||||
|
@ -146,14 +163,14 @@ void BreakpointsView::reloadData()
|
|||
{
|
||||
QString addr_text = QString("%1").arg(wBPList.bp[wI].addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
|
||||
mSoftBPTable->setCellContent(wI, 0, addr_text);
|
||||
mSoftBPTable->setCellContent(wI, 1, QString(wBPList.bp[wI].name));
|
||||
mSoftBPTable->setCellContent(wI, 1, QString::fromUtf8(wBPList.bp[wI].name));
|
||||
|
||||
QString label_text;
|
||||
char label[MAX_LABEL_SIZE] = "";
|
||||
if(DbgGetLabelAt(wBPList.bp[wI].addr, SEG_DEFAULT, label))
|
||||
label_text = "<" + QString(wBPList.bp[wI].mod) + "." + QString(label) + ">";
|
||||
label_text = "<" + QString::fromUtf8(wBPList.bp[wI].mod) + "." + QString::fromUtf8(label) + ">";
|
||||
else
|
||||
label_text = QString(wBPList.bp[wI].mod);
|
||||
label_text = QString::fromUtf8(wBPList.bp[wI].mod);
|
||||
mSoftBPTable->setCellContent(wI, 2, label_text);
|
||||
|
||||
if(wBPList.bp[wI].active == false)
|
||||
|
@ -186,14 +203,14 @@ void BreakpointsView::reloadData()
|
|||
{
|
||||
QString addr_text = QString("%1").arg(wBPList.bp[wI].addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
|
||||
mMemBPTable->setCellContent(wI, 0, addr_text);
|
||||
mMemBPTable->setCellContent(wI, 1, QString(wBPList.bp[wI].name));
|
||||
mMemBPTable->setCellContent(wI, 1, QString::fromUtf8(wBPList.bp[wI].name));
|
||||
|
||||
QString label_text;
|
||||
char label[MAX_LABEL_SIZE] = "";
|
||||
if(DbgGetLabelAt(wBPList.bp[wI].addr, SEG_DEFAULT, label))
|
||||
label_text = "<" + QString(wBPList.bp[wI].mod) + "." + QString(label) + ">";
|
||||
label_text = "<" + QString::fromUtf8(wBPList.bp[wI].mod) + "." + QString::fromUtf8(label) + ">";
|
||||
else
|
||||
label_text = QString(wBPList.bp[wI].mod);
|
||||
label_text = QString::fromUtf8(wBPList.bp[wI].mod);
|
||||
mMemBPTable->setCellContent(wI, 2, label_text);
|
||||
|
||||
if(wBPList.bp[wI].active == false)
|
||||
|
@ -217,6 +234,29 @@ void BreakpointsView::reloadData()
|
|||
}
|
||||
mMemBPTable->reloadData();
|
||||
|
||||
// DLL
|
||||
DbgGetBpList(bp_dll, &wBPList);
|
||||
mDLLBPTable->setRowCount(wBPList.count);
|
||||
for(wI = 0; wI < wBPList.count; wI++)
|
||||
{
|
||||
mDLLBPTable->setCellContent(wI, 0, QString::fromUtf8(wBPList.bp[wI].name));
|
||||
mDLLBPTable->setCellContent(wI, 1, QString::fromUtf8(wBPList.bp[wI].mod));
|
||||
|
||||
if(wBPList.bp[wI].active == false)
|
||||
mDLLBPTable->setCellContent(wI, 2, tr("Inactive"));
|
||||
else if(wBPList.bp[wI].enabled == true)
|
||||
mDLLBPTable->setCellContent(wI, 2, tr("Enabled"));
|
||||
else
|
||||
mDLLBPTable->setCellContent(wI, 2, tr("Disabled"));
|
||||
|
||||
mDLLBPTable->setCellContent(wI, 3, QString("%1").arg(wBPList.bp[wI].hitCount));
|
||||
mDLLBPTable->setCellContent(wI, 4, QString().fromUtf8(wBPList.bp[wI].logText));
|
||||
mDLLBPTable->setCellContent(wI, 5, QString().fromUtf8(wBPList.bp[wI].breakCondition));
|
||||
mDLLBPTable->setCellContent(wI, 6, wBPList.bp[wI].fastResume ? "X" : "");
|
||||
mDLLBPTable->setCellContent(wI, 7, QString().fromUtf8(wBPList.bp[wI].commandText));
|
||||
}
|
||||
mDLLBPTable->reloadData();
|
||||
|
||||
if(wBPList.count)
|
||||
BridgeFree(wBPList.bp);
|
||||
}
|
||||
|
@ -230,6 +270,7 @@ void BreakpointsView::setupRightClickContextMenu()
|
|||
setupSoftBPRightClickContextMenu();
|
||||
setupHardBPRightClickContextMenu();
|
||||
setupMemBPRightClickContextMenu();
|
||||
setupDLLBPRightClickContextMenu();
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
|
@ -717,6 +758,155 @@ void BreakpointsView::resetMemoryHitCountSlot()
|
|||
reloadData();
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************************
|
||||
DLL Context Menu Management
|
||||
************************************************************************************/
|
||||
void BreakpointsView::setupDLLBPRightClickContextMenu()
|
||||
{
|
||||
// Remove
|
||||
mDLLBPRemoveAction = new QAction(tr("Remove"), this);
|
||||
mDLLBPRemoveAction->setShortcutContext(Qt::WidgetShortcut);
|
||||
mDLLBPTable->addAction(mDLLBPRemoveAction);
|
||||
connect(mDLLBPRemoveAction, SIGNAL(triggered()), this, SLOT(removeDLLBPActionSlot()));
|
||||
|
||||
// Remove All
|
||||
mDLLBPRemoveAllAction = new QAction(tr("Remove All"), this);
|
||||
connect(mDLLBPRemoveAllAction, SIGNAL(triggered()), this, SLOT(removeAllDLLBPActionSlot()));
|
||||
|
||||
// Enable/Disable
|
||||
mDLLBPEnableDisableAction = new QAction(tr("Enable"), this);
|
||||
mDLLBPEnableDisableAction->setShortcutContext(Qt::WidgetShortcut);
|
||||
mDLLBPTable->addAction(mDLLBPEnableDisableAction);
|
||||
connect(mDLLBPEnableDisableAction, SIGNAL(triggered()), this, SLOT(enableDisableDLLBPActionSlot()));
|
||||
|
||||
// Reset hit count
|
||||
mDLLBPResetHitCountAction = new QAction(tr("Reset hit count"), this);
|
||||
mDLLBPTable->addAction(mDLLBPResetHitCountAction);
|
||||
connect(mDLLBPResetHitCountAction, SIGNAL(triggered()), this, SLOT(resetDLLHitCountSlot()));
|
||||
|
||||
// Enable All
|
||||
mDLLBPEnableAllAction = new QAction(tr("Enable All"), this);
|
||||
mDLLBPTable->addAction(mDLLBPEnableAllAction);
|
||||
connect(mDLLBPEnableAllAction, SIGNAL(triggered()), this, SLOT(enableAllDLLBPActionSlot()));
|
||||
|
||||
// Disable All
|
||||
mDLLBPDisableAllAction = new QAction(tr("Disable All"), this);
|
||||
mDLLBPTable->addAction(mDLLBPDisableAllAction);
|
||||
connect(mDLLBPDisableAllAction, SIGNAL(triggered()), this, SLOT(disableAllDLLBPActionSlot()));
|
||||
}
|
||||
|
||||
void BreakpointsView::DLLBPContextMenuSlot(const QPoint & pos)
|
||||
{
|
||||
StdTable* table = mDLLBPTable;
|
||||
if(table->getRowCount() != 0)
|
||||
{
|
||||
int wI = 0;
|
||||
QMenu wMenu(this);
|
||||
QString wName = table->getCellContent(table->getInitialSelection(), 1);
|
||||
BPMAP wBPList;
|
||||
|
||||
// Remove
|
||||
wMenu.addAction(mDLLBPRemoveAction);
|
||||
|
||||
// Enable/Disable
|
||||
DbgGetBpList(bp_dll, &wBPList);
|
||||
|
||||
for(wI = 0; wI < wBPList.count; wI++)
|
||||
{
|
||||
if(QString::fromUtf8(wBPList.bp[wI].mod) == wName)
|
||||
{
|
||||
if(wBPList.bp[wI].active == false)
|
||||
{
|
||||
mDLLBPEnableDisableAction->setText(tr("Enable"));
|
||||
wMenu.addAction(mDLLBPEnableDisableAction);
|
||||
}
|
||||
else if(wBPList.bp[wI].enabled == true)
|
||||
{
|
||||
mDLLBPEnableDisableAction->setText(tr("Disable"));
|
||||
wMenu.addAction(mDLLBPEnableDisableAction);
|
||||
}
|
||||
else
|
||||
{
|
||||
mDLLBPEnableDisableAction->setText(tr("Enable"));
|
||||
wMenu.addAction(mDLLBPEnableDisableAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(wBPList.count)
|
||||
BridgeFree(wBPList.bp);
|
||||
|
||||
// Conditional
|
||||
mCurrentType = bp_dll;
|
||||
wMenu.addAction(mEditBreakpointAction);
|
||||
wMenu.addAction(mDLLBPResetHitCountAction);
|
||||
|
||||
// Separator
|
||||
wMenu.addSeparator();
|
||||
|
||||
// Enable All
|
||||
wMenu.addAction(mDLLBPEnableAllAction);
|
||||
|
||||
// Disable All
|
||||
wMenu.addAction(mDLLBPDisableAllAction);
|
||||
|
||||
// Remove All
|
||||
wMenu.addAction(mDLLBPRemoveAllAction);
|
||||
|
||||
//Copy
|
||||
QMenu wCopyMenu(tr("&Copy"), this);
|
||||
table->setupCopyMenu(&wCopyMenu);
|
||||
if(wCopyMenu.actions().length())
|
||||
{
|
||||
wMenu.addSeparator();
|
||||
wMenu.addMenu(&wCopyMenu);
|
||||
}
|
||||
|
||||
wMenu.exec(table->mapToGlobal(pos));
|
||||
}
|
||||
}
|
||||
|
||||
void BreakpointsView::removeDLLBPActionSlot()
|
||||
{
|
||||
StdTable* table = mDLLBPTable;
|
||||
Breakpoints::removeBP(table->getCellContent(table->getInitialSelection(), 1));
|
||||
}
|
||||
|
||||
void BreakpointsView::enableDisableDLLBPActionSlot()
|
||||
{
|
||||
StdTable* table = mDLLBPTable;
|
||||
Breakpoints::toggleBPByDisabling(table->getCellContent(table->getInitialSelection(), 1));
|
||||
table->selectNext();
|
||||
}
|
||||
|
||||
void BreakpointsView::selectionChangedDLLSlot()
|
||||
{
|
||||
mCurrentType = bp_dll;
|
||||
}
|
||||
|
||||
void BreakpointsView::resetDLLHitCountSlot()
|
||||
{
|
||||
StdTable* table = mDLLBPTable;
|
||||
QString addrText = table->getCellContent(table->getInitialSelection(), 1);
|
||||
DbgCmdExecDirect(QString("ResetLibrarianBreakpointHitCount \"%1\"").arg(addrText).toUtf8().constData());
|
||||
reloadData();
|
||||
}
|
||||
|
||||
void BreakpointsView::enableAllDLLBPActionSlot()
|
||||
{
|
||||
DbgCmdExec("LibrarianEnableBreakPoint");
|
||||
}
|
||||
|
||||
void BreakpointsView::disableAllDLLBPActionSlot()
|
||||
{
|
||||
DbgCmdExec("LibrarianDisableBreakPoint");
|
||||
}
|
||||
|
||||
void BreakpointsView::removeAllDLLBPActionSlot()
|
||||
{
|
||||
DbgCmdExec("LibrarianRemoveBreakPoint");
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
Conditional Breakpoint Context Menu Management (Sub-menu only)
|
||||
************************************************************************************/
|
||||
|
@ -734,6 +924,10 @@ void BreakpointsView::editBreakpointSlot()
|
|||
case bp_memory:
|
||||
table = mMemBPTable;
|
||||
break;
|
||||
case bp_dll:
|
||||
table = mDLLBPTable;
|
||||
Breakpoints::editBP(mCurrentType, table->getCellContent(table->getInitialSelection(), 1), this);
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
class StdTable;
|
||||
class QVBoxLayout;
|
||||
class LabeledSplitter;
|
||||
class MenuBuilder;
|
||||
|
||||
class BreakpointsView : public QWidget
|
||||
{
|
||||
|
@ -17,6 +18,7 @@ public:
|
|||
void setupHardBPRightClickContextMenu();
|
||||
void setupSoftBPRightClickContextMenu();
|
||||
void setupMemBPRightClickContextMenu();
|
||||
void setupDLLBPRightClickContextMenu();
|
||||
|
||||
signals:
|
||||
void showCpu();
|
||||
|
@ -58,6 +60,16 @@ public slots:
|
|||
void selectionChangedMemorySlot();
|
||||
void resetMemoryHitCountSlot();
|
||||
|
||||
// DLL
|
||||
void DLLBPContextMenuSlot(const QPoint & pos);
|
||||
void removeDLLBPActionSlot();
|
||||
void removeAllDLLBPActionSlot();
|
||||
void enableDisableDLLBPActionSlot();
|
||||
void enableAllDLLBPActionSlot();
|
||||
void disableAllDLLBPActionSlot();
|
||||
void selectionChangedDLLSlot();
|
||||
void resetDLLHitCountSlot();
|
||||
|
||||
// Conditional
|
||||
void editBreakpointSlot();
|
||||
|
||||
|
@ -67,6 +79,7 @@ private:
|
|||
StdTable* mHardBPTable;
|
||||
StdTable* mSoftBPTable;
|
||||
StdTable* mMemBPTable;
|
||||
StdTable* mDLLBPTable;
|
||||
// Conditional BP Context Menu
|
||||
BPXTYPE mCurrentType;
|
||||
QAction* mEditBreakpointAction;
|
||||
|
@ -94,6 +107,14 @@ private:
|
|||
QAction* mMemBPResetHitCountAction;
|
||||
QAction* mMemBPEnableAllAction;
|
||||
QAction* mMemBPDisableAllAction;
|
||||
|
||||
// DLL BP Context Menu
|
||||
QAction* mDLLBPRemoveAction;
|
||||
QAction* mDLLBPRemoveAllAction;
|
||||
QAction* mDLLBPEnableDisableAction;
|
||||
QAction* mDLLBPResetHitCountAction;
|
||||
QAction* mDLLBPEnableAllAction;
|
||||
QAction* mDLLBPDisableAllAction;
|
||||
};
|
||||
|
||||
#endif // BREAKPOINTSVIEW_H
|
||||
|
|
|
@ -10,7 +10,14 @@ EditBreakpointDialog::EditBreakpointDialog(QWidget* parent, const BRIDGEBP & bp)
|
|||
ui->setupUi(this);
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint);
|
||||
setFixedSize(this->size()); //fixed size
|
||||
setWindowTitle(QString(tr("Edit Breakpoint %1")).arg(ToHexString(bp.addr)));
|
||||
if(bp.type == bp_dll)
|
||||
{
|
||||
setWindowTitle(QString(tr("Edit Breakpoint %1")).arg(QString::fromUtf8(bp.mod)));
|
||||
}
|
||||
else
|
||||
{
|
||||
setWindowTitle(QString(tr("Edit Breakpoint %1")).arg(ToHexString(bp.addr)));
|
||||
}
|
||||
setWindowIcon(DIcon("breakpoint.png"));
|
||||
loadFromBp();
|
||||
}
|
||||
|
@ -35,8 +42,10 @@ void EditBreakpointDialog::loadFromBp()
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
void copyTruncate(T & dest, const QString & src)
|
||||
void copyTruncate(T & dest, QString src)
|
||||
{
|
||||
src.replace(QChar('\\'), QString("\\\\"));
|
||||
src.replace(QChar('"'), QString("\\\""));
|
||||
strncpy_s(dest, src.toUtf8().constData(), _TRUNCATE);
|
||||
}
|
||||
|
||||
|
|
|
@ -112,13 +112,16 @@ void HandlesView::handlesTableContextMenuSlot(const QPoint & pos)
|
|||
StdTable & table = *mHandlesTable;
|
||||
QMenu wMenu;
|
||||
wMenu.addAction(mActionRefresh);
|
||||
wMenu.addAction(mActionCloseHandle);
|
||||
QMenu wCopyMenu(tr("&Copy"));
|
||||
table.setupCopyMenu(&wCopyMenu);
|
||||
if(wCopyMenu.actions().length())
|
||||
if(mHandlesTable->getRowCount() != 0)
|
||||
{
|
||||
wMenu.addSeparator();
|
||||
wMenu.addMenu(&wCopyMenu);
|
||||
wMenu.addAction(mActionCloseHandle);
|
||||
QMenu wCopyMenu(tr("&Copy"));
|
||||
table.setupCopyMenu(&wCopyMenu);
|
||||
if(wCopyMenu.actions().length())
|
||||
{
|
||||
wMenu.addSeparator();
|
||||
wMenu.addMenu(&wCopyMenu);
|
||||
}
|
||||
}
|
||||
wMenu.exec(table.mapToGlobal(pos));
|
||||
}
|
||||
|
@ -128,12 +131,15 @@ void HandlesView::tcpConnectionsTableContextMenuSlot(const QPoint & pos)
|
|||
StdTable & table = *mTcpConnectionsTable;
|
||||
QMenu wMenu;
|
||||
wMenu.addAction(mActionRefresh);
|
||||
QMenu wCopyMenu(tr("&Copy"));
|
||||
table.setupCopyMenu(&wCopyMenu);
|
||||
if(wCopyMenu.actions().length())
|
||||
if(mTcpConnectionsTable->getRowCount() != 0)
|
||||
{
|
||||
wMenu.addSeparator();
|
||||
wMenu.addMenu(&wCopyMenu);
|
||||
QMenu wCopyMenu(tr("&Copy"));
|
||||
table.setupCopyMenu(&wCopyMenu);
|
||||
if(wCopyMenu.actions().length())
|
||||
{
|
||||
wMenu.addSeparator();
|
||||
wMenu.addMenu(&wCopyMenu);
|
||||
}
|
||||
}
|
||||
wMenu.exec(table.mapToGlobal(pos));
|
||||
}
|
||||
|
@ -143,7 +149,7 @@ void HandlesView::privilegesTableContextMenuSlot(const QPoint & pos)
|
|||
{
|
||||
StdTable & table = *mPrivilegesTable;
|
||||
QMenu wMenu;
|
||||
bool isValid = (mPrivilegesTable->getCellContent(mPrivilegesTable->getInitialSelection(), 1) != tr("Unknown"));
|
||||
bool isValid = (mPrivilegesTable->getRowCount() != 0 && mPrivilegesTable->getCellContent(mPrivilegesTable->getInitialSelection(), 1) != tr("Unknown"));
|
||||
wMenu.addAction(mActionRefresh);
|
||||
if(isValid)
|
||||
{
|
||||
|
|
|
@ -256,7 +256,7 @@ MainWindow::MainWindow(QWidget* parent)
|
|||
connect(ui->actionCommand, SIGNAL(triggered()), this, SLOT(setFocusToCommandBar()));
|
||||
makeCommandAction(ui->actionClose, "stop");
|
||||
connect(ui->actionMemoryMap, SIGNAL(triggered()), this, SLOT(displayMemMapWidget()));
|
||||
makeCommandAction(ui->actionRun, "run");
|
||||
connect(ui->actionRun, SIGNAL(triggered()), this, SLOT(runSlot()));
|
||||
makeCommandAction(ui->actionRtr, "rtr");
|
||||
connect(ui->actionLog, SIGNAL(triggered()), this, SLOT(displayLogWidget()));
|
||||
connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(displayAboutWidget()));
|
||||
|
@ -826,6 +826,14 @@ void MainWindow::openFile()
|
|||
mCpuWidget->setDisasmFocus();
|
||||
}
|
||||
|
||||
void MainWindow::runSlot()
|
||||
{
|
||||
if(DbgIsDebugging())
|
||||
DbgCmdExec("run");
|
||||
else
|
||||
restartDebugging();
|
||||
}
|
||||
|
||||
void MainWindow::restartDebugging()
|
||||
{
|
||||
if(!mMRUList.size())
|
||||
|
|
|
@ -70,6 +70,7 @@ public slots:
|
|||
void restartDebugging();
|
||||
void displayBreakpointWidget();
|
||||
void updateWindowTitleSlot(QString filename);
|
||||
void runSlot();
|
||||
void execTRBit();
|
||||
void execTRByte();
|
||||
void execTRWord();
|
||||
|
|
|
@ -3,7 +3,7 @@ struct ActionShortcut
|
|||
QAction* action;
|
||||
QString shortcut;
|
||||
|
||||
ActionShortcut(QAction* action, const char* shortcut)
|
||||
inline ActionShortcut(QAction* action, const char* shortcut)
|
||||
: action(action),
|
||||
shortcut(shortcut)
|
||||
{
|
||||
|
|
|
@ -60,16 +60,21 @@ void Breakpoints::enableBP(const BRIDGEBP & bp)
|
|||
|
||||
if(bp.type == bp_hardware)
|
||||
{
|
||||
wCmd = "bphwe " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
|
||||
wCmd = QString("bphwe \"%1\"").arg(ToPtrString(bp.addr));
|
||||
}
|
||||
else if(bp.type == bp_normal)
|
||||
{
|
||||
wCmd = "be " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
|
||||
wCmd = QString("be \"%1\"").arg(ToPtrString(bp.addr));
|
||||
}
|
||||
else if(bp.type == bp_memory)
|
||||
{
|
||||
wCmd = "bpme " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
|
||||
wCmd = QString("bpme \"%1\"").arg(ToPtrString(bp.addr));
|
||||
}
|
||||
else if(bp.type == bp_dll)
|
||||
{
|
||||
wCmd = QString("LibrarianEnableBreakPoint \"%1\"").arg(QString::fromUtf8(bp.mod));
|
||||
}
|
||||
|
||||
|
||||
DbgCmdExec(wCmd.toUtf8().constData());
|
||||
}
|
||||
|
@ -117,15 +122,19 @@ void Breakpoints::disableBP(const BRIDGEBP & bp)
|
|||
|
||||
if(bp.type == bp_hardware)
|
||||
{
|
||||
wCmd = "bphwd " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
|
||||
wCmd = QString("bphwd \"%1\"").arg(ToPtrString(bp.addr));
|
||||
}
|
||||
else if(bp.type == bp_normal)
|
||||
{
|
||||
wCmd = "bd " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
|
||||
wCmd = QString("bd \"%1\"").arg(ToPtrString(bp.addr));
|
||||
}
|
||||
else if(bp.type == bp_memory)
|
||||
{
|
||||
wCmd = "bpmd " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
|
||||
wCmd = QString("bpmd \"%1\"").arg(ToPtrString(bp.addr));
|
||||
}
|
||||
else if(bp.type == bp_dll)
|
||||
{
|
||||
wCmd = QString("LibrarianDisableBreakPoint \"%1\"").arg(QString::fromUtf8(bp.mod));
|
||||
}
|
||||
|
||||
DbgCmdExec(wCmd.toUtf8().constData());
|
||||
|
@ -175,22 +184,20 @@ void Breakpoints::removeBP(const BRIDGEBP & bp)
|
|||
switch(bp.type)
|
||||
{
|
||||
case bp_normal:
|
||||
{
|
||||
wCmd = "bc " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
|
||||
}
|
||||
break;
|
||||
wCmd = QString("bc \"%1\"").arg(ToPtrString(bp.addr));
|
||||
break;
|
||||
|
||||
case bp_hardware:
|
||||
{
|
||||
wCmd = "bphc " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
|
||||
}
|
||||
break;
|
||||
wCmd = QString("bphc \"%1\"").arg(ToPtrString(bp.addr));
|
||||
break;
|
||||
|
||||
case bp_memory:
|
||||
{
|
||||
wCmd = "bpmc " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
|
||||
}
|
||||
break;
|
||||
wCmd = QString("bpmc \"%1\"").arg(ToPtrString(bp.addr));
|
||||
break;
|
||||
|
||||
case bp_dll:
|
||||
wCmd = QString("bcdll \"%1\"").arg(QString::fromUtf8(bp.mod));
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
|
@ -232,6 +239,25 @@ void Breakpoints::removeBP(BPXTYPE type, duint va)
|
|||
BridgeFree(wBPList.bp);
|
||||
}
|
||||
|
||||
void Breakpoints::removeBP(const QString & DLLName)
|
||||
{
|
||||
BPMAP wBPList;
|
||||
|
||||
// Get breakpoints list
|
||||
DbgGetBpList(bp_dll, &wBPList);
|
||||
|
||||
// Find breakpoint at DLLName
|
||||
for(int wI = 0; wI < wBPList.count; wI++)
|
||||
{
|
||||
if(QString::fromUtf8(wBPList.bp[wI].mod) == DLLName)
|
||||
{
|
||||
removeBP(wBPList.bp[wI]);
|
||||
}
|
||||
}
|
||||
if(wBPList.count)
|
||||
BridgeFree(wBPList.bp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Toggle the given breakpoint by disabling it when enabled.@n
|
||||
* If breakpoint is initially active and enabled, it will be disabled.@n
|
||||
|
@ -279,6 +305,25 @@ void Breakpoints::toggleBPByDisabling(BPXTYPE type, duint va)
|
|||
BridgeFree(wBPList.bp);
|
||||
}
|
||||
|
||||
void Breakpoints::toggleBPByDisabling(const QString & DLLName)
|
||||
{
|
||||
BPMAP wBPList;
|
||||
|
||||
// Get breakpoints list
|
||||
DbgGetBpList(bp_dll, &wBPList);
|
||||
|
||||
// Find breakpoint at module name
|
||||
for(int wI = 0; wI < wBPList.count; wI++)
|
||||
{
|
||||
if(QString::fromUtf8(wBPList.bp[wI].mod) == DLLName)
|
||||
{
|
||||
toggleBPByDisabling(wBPList.bp[wI]);
|
||||
}
|
||||
}
|
||||
if(wBPList.count)
|
||||
BridgeFree(wBPList.bp);
|
||||
}
|
||||
|
||||
void Breakpoints::toggleAllBP(BPXTYPE type, bool bEnable)
|
||||
{
|
||||
BPMAP wBPList;
|
||||
|
@ -410,9 +455,14 @@ void Breakpoints::toggleBPByRemoving(BPXTYPE type, duint va)
|
|||
|
||||
void Breakpoints::editBP(BPXTYPE type, const QString & addrText, QWidget* widget)
|
||||
{
|
||||
duint addr = addrText.toULongLong(nullptr, 16);
|
||||
BRIDGEBP bridgebp;
|
||||
if(!DbgFunctions()->GetBridgeBp(type, addr, &bridgebp))
|
||||
if(type != bp_dll)
|
||||
{
|
||||
duint addr = addrText.toULongLong(nullptr, 16);
|
||||
if(!DbgFunctions()->GetBridgeBp(type, addr, &bridgebp))
|
||||
return;
|
||||
}
|
||||
else if(!DbgFunctions()->GetBridgeBp(type, reinterpret_cast<duint>(addrText.toUtf8().constData()), &bridgebp))
|
||||
return;
|
||||
EditBreakpointDialog dialog(widget, bridgebp);
|
||||
if(dialog.exec() != QDialog::Accepted)
|
||||
|
@ -431,7 +481,7 @@ void Breakpoints::editBP(BPXTYPE type, const QString & addrText, QWidget* widget
|
|||
exec(QString("SetBreakpointLogCondition %1, \"%2\"").arg(addrText).arg(bp.logCondition));
|
||||
exec(QString("SetBreakpointCommand %1, \"%2\"").arg(addrText).arg(bp.commandText));
|
||||
exec(QString("SetBreakpointCommandCondition %1, \"%2\"").arg(addrText).arg(bp.commandCondition));
|
||||
exec(QString("ResetBreakpointHitCount %1, %2").arg(addrText).arg(bp.hitCount));
|
||||
exec(QString("ResetBreakpointHitCount %1, %2").arg(addrText).arg(ToPtrString(bp.hitCount)));
|
||||
exec(QString("SetBreakpointFastResume %1, %2").arg(addrText).arg(bp.fastResume));
|
||||
exec(QString("SetBreakpointSilent %1, %2").arg(addrText).arg(bp.silent));
|
||||
exec(QString("SetBreakpointSingleshoot %1, %2").arg(addrText).arg(bp.singleshoot));
|
||||
|
@ -443,7 +493,7 @@ void Breakpoints::editBP(BPXTYPE type, const QString & addrText, QWidget* widget
|
|||
exec(QString("SetHardwareBreakpointLogCondition %1, \"%2\"").arg(addrText).arg(bp.logCondition));
|
||||
exec(QString("SetHardwareBreakpointCommand %1, \"%2\"").arg(addrText).arg(bp.commandText));
|
||||
exec(QString("SetHardwareBreakpointCommandCondition %1, \"%2\"").arg(addrText).arg(bp.commandCondition));
|
||||
exec(QString("ResetHardwareBreakpointHitCount %1, %2").arg(addrText).arg(bp.hitCount));
|
||||
exec(QString("ResetHardwareBreakpointHitCount %1, %2").arg(addrText).arg(ToPtrString(bp.hitCount)));
|
||||
exec(QString("SetHardwareBreakpointFastResume %1, %2").arg(addrText).arg(bp.fastResume));
|
||||
exec(QString("SetHardwareBreakpointSilent %1, %2").arg(addrText).arg(bp.silent));
|
||||
exec(QString("SetHardwareBreakpointSingleshoot %1, %2").arg(addrText).arg(bp.singleshoot));
|
||||
|
@ -455,11 +505,23 @@ void Breakpoints::editBP(BPXTYPE type, const QString & addrText, QWidget* widget
|
|||
exec(QString("SetMemoryBreakpointLogCondition %1, \"%2\"").arg(addrText).arg(bp.logCondition));
|
||||
exec(QString("SetMemoryBreakpointCommand %1, \"%2\"").arg(addrText).arg(bp.commandText));
|
||||
exec(QString("SetMemoryBreakpointCommandCondition %1, \"%2\"").arg(addrText).arg(bp.commandCondition));
|
||||
exec(QString("ResetMemoryBreakpointHitCount %1, %2").arg(addrText).arg(bp.hitCount));
|
||||
exec(QString("ResetMemoryBreakpointHitCount %1, %2").arg(addrText).arg(ToPtrString(bp.hitCount)));
|
||||
exec(QString("SetMemoryBreakpointFastResume %1, %2").arg(addrText).arg(bp.fastResume));
|
||||
exec(QString("SetMemoryBreakpointSilent %1, %2").arg(addrText).arg(bp.silent));
|
||||
exec(QString("SetMemoryBreakpointSingleshoot %1, %2").arg(addrText).arg(bp.singleshoot));
|
||||
break;
|
||||
case bp_dll:
|
||||
exec(QString("SetLibrarianBreakpointName \"%1\", \"\"%2\"\"").arg(addrText).arg(bp.name));
|
||||
exec(QString("SetLibrarianBreakpointCondition \"%1\", \"%2\"").arg(addrText).arg(bp.breakCondition));
|
||||
exec(QString("SetLibrarianBreakpointLog \"%1\", \"%2\"").arg(addrText).arg(bp.logText));
|
||||
exec(QString("SetLibrarianBreakpointLogCondition \"%1\", \"%2\"").arg(addrText).arg(bp.logCondition));
|
||||
exec(QString("SetLibrarianBreakpointCommand \"%1\", \"%2\"").arg(addrText).arg(bp.commandText));
|
||||
exec(QString("SetLibrarianBreakpointCommandCondition \"%1\", \"%2\"").arg(addrText).arg(bp.commandCondition));
|
||||
exec(QString("ResetLibrarianBreakpointHitCount \"%1\", %2").arg(addrText).arg(ToPtrString(bp.hitCount)));
|
||||
exec(QString("SetLibrarianBreakpointFastResume \"%1\", %2").arg(addrText).arg(bp.fastResume));
|
||||
exec(QString("SetLibrarianBreakpointSilent \"%1\", %2").arg(addrText).arg(bp.silent));
|
||||
exec(QString("SetLibrarianBreakpointSingleshoot \"%1\", %2").arg(addrText).arg(bp.singleshoot));
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -24,8 +24,10 @@ public:
|
|||
static void disableBP(BPXTYPE type, duint va);
|
||||
static void removeBP(const BRIDGEBP & bp);
|
||||
static void removeBP(BPXTYPE type, duint va);
|
||||
static void removeBP(const QString & DLLName);
|
||||
static void toggleBPByDisabling(const BRIDGEBP & bp);
|
||||
static void toggleBPByDisabling(BPXTYPE type, duint va);
|
||||
static void toggleBPByDisabling(const QString & DLLName);
|
||||
static void toggleAllBP(BPXTYPE type, bool bEnable);
|
||||
static void toggleBPByRemoving(BPXTYPE type, duint va);
|
||||
static BPXSTATE BPState(BPXTYPE type, duint va);
|
||||
|
|
|
@ -218,6 +218,7 @@ Configuration::Configuration() : QObject(), noMoreMsgbox(false)
|
|||
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "SoftwareBreakpoint", 10);
|
||||
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "HardwareBreakpoint", 10);
|
||||
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "MemoryBreakpoint", 10);
|
||||
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "DLLBreakpoint", 8);
|
||||
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "MemoryMap", 7);
|
||||
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "CallStack", 4);
|
||||
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "SEH", 4);
|
||||
|
|
Loading…
Reference in New Issue