BRIDGE+DBG+GUI: reduced the code for conditional breakpoints + added commandCondition and logCondition (when not set the behavior stays the same as before)
This commit is contained in:
parent
40555f1fb9
commit
490b0ff878
|
|
@ -62,7 +62,7 @@ BRIDGE_IMPEXP int BridgeGetDbgVersion();
|
|||
#define MAX_IMPORT_SIZE 65536
|
||||
#define MAX_BREAKPOINT_SIZE 256
|
||||
#define MAX_CONDITIONAL_EXPR_SIZE 256
|
||||
#define MAX_CONDITIONAL_LOG_SIZE 256
|
||||
#define MAX_CONDITIONAL_TEXT_SIZE 256
|
||||
#define MAX_SCRIPT_LINE_SIZE 2048
|
||||
#define MAX_THREAD_NAME_SIZE 256
|
||||
#define MAX_STRING_SIZE 512
|
||||
|
|
@ -326,9 +326,11 @@ typedef struct
|
|||
// extended part
|
||||
unsigned int hitCount;
|
||||
bool fastResume;
|
||||
char condition[MAX_CONDITIONAL_EXPR_SIZE];
|
||||
char log[MAX_CONDITIONAL_LOG_SIZE];
|
||||
char hitCmd[MAX_CONDITIONAL_EXPR_SIZE];
|
||||
char breakCondition[MAX_CONDITIONAL_EXPR_SIZE];
|
||||
char logText[MAX_CONDITIONAL_TEXT_SIZE];
|
||||
char logCondition[MAX_CONDITIONAL_EXPR_SIZE];
|
||||
char commandText[MAX_CONDITIONAL_EXPR_SIZE];
|
||||
char commandCondition[MAX_CONDITIONAL_TEXT_SIZE];
|
||||
} BRIDGEBP;
|
||||
|
||||
typedef struct
|
||||
|
|
|
|||
|
|
@ -217,18 +217,18 @@ bool BpSetTitanType(duint Address, BP_TYPE Type, int TitanType)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool BpSetCondition(duint Address, BP_TYPE Type, const char* Condition)
|
||||
bool BpSetBreakCondition(duint Address, BP_TYPE Type, const char* Condition)
|
||||
{
|
||||
ASSERT_DEBUGGING("Command function call");
|
||||
EXCLUSIVE_ACQUIRE(LockBreakpoints);
|
||||
|
||||
// Set breakpoint condition
|
||||
// Set breakpoint breakCondition
|
||||
BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address);
|
||||
|
||||
if(!bpInfo)
|
||||
return false;
|
||||
|
||||
strcpy_s(bpInfo->condition, Condition);
|
||||
strcpy_s(bpInfo->breakCondition, Condition);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -237,17 +237,32 @@ bool BpSetLogText(duint Address, BP_TYPE Type, const char* Log)
|
|||
ASSERT_DEBUGGING("Command function call");
|
||||
EXCLUSIVE_ACQUIRE(LockBreakpoints);
|
||||
|
||||
// Set breakpoint log
|
||||
// Set breakpoint logText
|
||||
BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address);
|
||||
|
||||
if(!bpInfo)
|
||||
return false;
|
||||
|
||||
strcpy_s(bpInfo->logText, MAX_CONDITIONAL_LOG_SIZE, Log);
|
||||
strcpy_s(bpInfo->logText, Log);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BpSetHitCommand(duint Address, BP_TYPE Type, const char* Cmd)
|
||||
bool BpSetLogCondition(duint Address, BP_TYPE Type, const char* Condition)
|
||||
{
|
||||
ASSERT_DEBUGGING("Command function call");
|
||||
EXCLUSIVE_ACQUIRE(LockBreakpoints);
|
||||
|
||||
// Set breakpoint logText
|
||||
BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address);
|
||||
|
||||
if(!bpInfo)
|
||||
return false;
|
||||
|
||||
strcpy_s(bpInfo->logCondition, Condition);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BpSetCommandText(duint Address, BP_TYPE Type, const char* Cmd)
|
||||
{
|
||||
ASSERT_DEBUGGING("Command function call");
|
||||
EXCLUSIVE_ACQUIRE(LockBreakpoints);
|
||||
|
|
@ -258,7 +273,22 @@ bool BpSetHitCommand(duint Address, BP_TYPE Type, const char* Cmd)
|
|||
if(!bpInfo)
|
||||
return false;
|
||||
|
||||
strcpy_s(bpInfo->hitcmd, MAX_CONDITIONAL_EXPR_SIZE, Cmd);
|
||||
strcpy_s(bpInfo->commandText, Cmd);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BpSetCommandCondition(duint Address, BP_TYPE Type, const char* Condition)
|
||||
{
|
||||
ASSERT_DEBUGGING("Command function call");
|
||||
EXCLUSIVE_ACQUIRE(LockBreakpoints);
|
||||
|
||||
// Set breakpoint hit command
|
||||
BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address);
|
||||
|
||||
if(!bpInfo)
|
||||
return false;
|
||||
|
||||
strcpy_s(bpInfo->commandCondition, Condition);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -381,9 +411,11 @@ void BpToBridge(const BREAKPOINT* Bp, BRIDGEBP* BridgeBp)
|
|||
memset(BridgeBp, 0, sizeof(BRIDGEBP));
|
||||
strcpy_s(BridgeBp->mod, Bp->mod);
|
||||
strcpy_s(BridgeBp->name, Bp->name);
|
||||
strcpy_s(BridgeBp->condition, Bp->condition);
|
||||
strcpy_s(BridgeBp->log, Bp->logText);
|
||||
strcpy_s(BridgeBp->hitCmd, Bp->hitcmd);
|
||||
strcpy_s(BridgeBp->breakCondition, Bp->breakCondition);
|
||||
strcpy_s(BridgeBp->logText, Bp->logText);
|
||||
strcpy_s(BridgeBp->logCondition, Bp->logCondition);
|
||||
strcpy_s(BridgeBp->commandText, Bp->commandText);
|
||||
strcpy_s(BridgeBp->commandCondition, Bp->commandCondition);
|
||||
|
||||
BridgeBp->active = Bp->active;
|
||||
BridgeBp->addr = Bp->addr;
|
||||
|
|
@ -452,10 +484,12 @@ void BpCacheSave(JSON Root)
|
|||
json_object_set_new(jsonObj, "titantype", json_hex(breakpoint.titantype));
|
||||
json_object_set_new(jsonObj, "name", json_string(breakpoint.name));
|
||||
json_object_set_new(jsonObj, "module", json_string(breakpoint.mod));
|
||||
json_object_set_new(jsonObj, "condition", json_string(breakpoint.condition));
|
||||
json_object_set_new(jsonObj, "log", json_string(breakpoint.logText));
|
||||
json_object_set_new(jsonObj, "hitcommand", json_string(breakpoint.hitcmd));
|
||||
json_object_set_new(jsonObj, "fastresume", json_boolean(breakpoint.fastResume));
|
||||
json_object_set_new(jsonObj, "breakCondition", json_string(breakpoint.breakCondition));
|
||||
json_object_set_new(jsonObj, "logText", json_string(breakpoint.logText));
|
||||
json_object_set_new(jsonObj, "logCondition", json_string(breakpoint.logCondition));
|
||||
json_object_set_new(jsonObj, "commandText", json_string(breakpoint.commandText));
|
||||
json_object_set_new(jsonObj, "commandCondition", json_string(breakpoint.commandCondition));
|
||||
json_object_set_new(jsonObj, "fastResume", json_boolean(breakpoint.fastResume));
|
||||
json_array_append_new(jsonBreakpoints, jsonObj);
|
||||
}
|
||||
|
||||
|
|
@ -466,6 +500,14 @@ void BpCacheSave(JSON Root)
|
|||
json_decref(jsonBreakpoints);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void loadStringValue(JSON value, T dest, const char* key)
|
||||
{
|
||||
auto text = json_string_value(json_object_get(value, key));
|
||||
if(text)
|
||||
strcpy_s(dest, _TRUNCATE, text);
|
||||
}
|
||||
|
||||
void BpCacheLoad(JSON Root)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockBreakpoints);
|
||||
|
|
@ -494,33 +536,17 @@ void BpCacheLoad(JSON Root)
|
|||
breakpoint.enabled = json_boolean_value(json_object_get(value, "enabled"));
|
||||
breakpoint.titantype = (DWORD)json_hex_value(json_object_get(value, "titantype"));
|
||||
|
||||
// Name
|
||||
const char* text = json_string_value(json_object_get(value, "name"));
|
||||
if(text)
|
||||
strcpy_s(breakpoint.name, text);
|
||||
|
||||
// Module
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(breakpoint.mod, mod);
|
||||
|
||||
// Condition
|
||||
text = json_string_value(json_object_get(value, "condition"));
|
||||
if(text)
|
||||
strcpy_s(breakpoint.condition, text);
|
||||
|
||||
// Log string
|
||||
text = json_string_value(json_object_get(value, "log"));
|
||||
if(text)
|
||||
strcpy_s(breakpoint.logText, text);
|
||||
|
||||
// Hit command
|
||||
text = json_string_value(json_object_get(value, "hitcommand"));
|
||||
if(text)
|
||||
strcpy_s(breakpoint.hitcmd, text);
|
||||
// String values
|
||||
loadStringValue(value, breakpoint.name, "name");
|
||||
loadStringValue(value, breakpoint.mod, "module");
|
||||
loadStringValue(value, breakpoint.breakCondition, "breakCondition");
|
||||
loadStringValue(value, breakpoint.logText, "logText");
|
||||
loadStringValue(value, breakpoint.logCondition, "logCondition");
|
||||
loadStringValue(value, breakpoint.commandText, "commandText");
|
||||
loadStringValue(value, breakpoint.commandCondition, "commandCondition");
|
||||
|
||||
// Fast resume
|
||||
breakpoint.fastResume = json_boolean_value(json_object_get(value, "fastresume"));
|
||||
breakpoint.fastResume = json_boolean_value(json_object_get(value, "fastResume"));
|
||||
|
||||
// Build the hash map key: MOD_HASH + ADDRESS
|
||||
duint key = ModHashFromName(breakpoint.mod) + breakpoint.addr;
|
||||
|
|
|
|||
|
|
@ -19,20 +19,22 @@ enum BP_TYPE
|
|||
|
||||
struct BREAKPOINT
|
||||
{
|
||||
duint addr;
|
||||
bool enabled;
|
||||
bool singleshoot;
|
||||
bool active;
|
||||
unsigned short oldbytes;
|
||||
BP_TYPE type;
|
||||
DWORD titantype;
|
||||
char name[MAX_BREAKPOINT_SIZE];
|
||||
char mod[MAX_MODULE_SIZE];
|
||||
char condition[MAX_CONDITIONAL_EXPR_SIZE]; // condition to stop. If true, debugger halts.
|
||||
char logText[MAX_CONDITIONAL_LOG_SIZE]; // text to log.
|
||||
char hitcmd[MAX_CONDITIONAL_EXPR_SIZE]; // script command to execute.
|
||||
uint32 hitcount; // hit counter
|
||||
bool fastResume; // if true, debugger resumes without any GUI/Script/Plugin interaction.
|
||||
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
|
||||
unsigned short oldbytes; // original bytes (for software breakpoitns)
|
||||
BP_TYPE type; // breakpoint type
|
||||
DWORD titantype; // type passed to titanengine
|
||||
char name[MAX_BREAKPOINT_SIZE]; // breakpoint name
|
||||
char mod[MAX_MODULE_SIZE]; // module name
|
||||
char breakCondition[MAX_CONDITIONAL_EXPR_SIZE]; // condition to stop. If true, debugger halts.
|
||||
char logText[MAX_CONDITIONAL_TEXT_SIZE]; // text to log.
|
||||
char logCondition[MAX_CONDITIONAL_EXPR_SIZE]; // condition to log
|
||||
char commandText[MAX_CONDITIONAL_TEXT_SIZE]; // script command to execute.
|
||||
char commandCondition[MAX_CONDITIONAL_EXPR_SIZE]; // condition to execute the command
|
||||
uint32 hitcount; // hit counter
|
||||
bool fastResume; // if true, debugger resumes without any GUI/Script/Plugin interaction.
|
||||
};
|
||||
|
||||
// Breakpoint enumeration callback
|
||||
|
|
@ -47,9 +49,11 @@ 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 BpSetCondition(duint Address, BP_TYPE Type, const char* Condition);
|
||||
bool BpSetBreakCondition(duint Address, BP_TYPE Type, const char* Condition);
|
||||
bool BpSetLogText(duint Address, BP_TYPE Type, const char* Log);
|
||||
bool BpSetHitCommand(duint Address, BP_TYPE Type, const char* Cmd);
|
||||
bool BpSetLogCondition(duint Address, BP_TYPE Type, const char* Condition);
|
||||
bool BpSetCommandText(duint Address, BP_TYPE Type, const char* Cmd);
|
||||
bool BpSetCommandCondition(duint Address, BP_TYPE Type, const char* Condition);
|
||||
bool BpSetFastResume(duint Address, BP_TYPE Type, bool fastResume);
|
||||
bool BpEnumAll(BPENUMCALLBACK EnumCallback, const char* Module);
|
||||
bool BpEnumAll(BPENUMCALLBACK EnumCallback);
|
||||
|
|
|
|||
|
|
@ -270,39 +270,6 @@ void DebugUpdateStack(duint dumpAddr, duint csp, bool forceDump)
|
|||
GuiStackDumpAt(dumpAddr, csp);
|
||||
}
|
||||
|
||||
void BreakpointProlog(duint condition, BREAKPOINT & bp, PLUG_CB_BREAKPOINT & bpInfo)
|
||||
{
|
||||
// update GUI
|
||||
if(condition != 0)
|
||||
{
|
||||
GuiSetDebugState(paused);
|
||||
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
}
|
||||
// plugin interaction
|
||||
lock(WAITID_RUN);
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
memset(&pauseInfo, 0, sizeof(pauseInfo));
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
plugincbcall(CB_BREAKPOINT, &bpInfo);
|
||||
// conditional
|
||||
if(bp.logText[0] != 0)
|
||||
{
|
||||
dprintf("%s\n", stringformatinline(bp.logText).c_str());
|
||||
}
|
||||
if(bp.hitcmd[0] != 0 && condition != 0)
|
||||
{
|
||||
DbgCmdExec(bp.hitcmd);
|
||||
}
|
||||
if(condition == 0)
|
||||
{
|
||||
unlock(WAITID_RUN);
|
||||
SetForegroundWindow(GuiGetWindowHandle());
|
||||
bSkipExceptions = false;
|
||||
}
|
||||
//lock
|
||||
wait(WAITID_RUN);
|
||||
}
|
||||
|
||||
static void printSoftBpInfo(const BREAKPOINT & bp)
|
||||
{
|
||||
auto bptype = "INT3";
|
||||
|
|
@ -414,158 +381,164 @@ static void printMemBpInfo(const BREAKPOINT & bp, const void* ExceptionAddress)
|
|||
}
|
||||
}
|
||||
|
||||
void cbUserBreakpoint()
|
||||
static bool getConditionValue(const char* expression)
|
||||
{
|
||||
auto word = *(uint16*)expression;
|
||||
if(word == '0') // short circuit for condition "0\0"
|
||||
return false;
|
||||
if(word == '1') //short circuit for condition "1\0"
|
||||
return true;
|
||||
duint value;
|
||||
if(valfromstring(expression, &value))
|
||||
return value != 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void getConditionValues(const BREAKPOINT & bp, bool & breakCondition, bool & logCondition, bool & commandCondition)
|
||||
{
|
||||
if(*bp.breakCondition)
|
||||
breakCondition = getConditionValue(bp.breakCondition);
|
||||
else
|
||||
breakCondition = true; //break if no condition is set
|
||||
if(*bp.logCondition)
|
||||
logCondition = getConditionValue(bp.logCondition);
|
||||
else
|
||||
logCondition = true; //log if no condition is set
|
||||
if(*bp.commandCondition)
|
||||
commandCondition = getConditionValue(bp.commandCondition);
|
||||
else
|
||||
commandCondition = breakCondition; //if no condition is set, execute the command when the debugger would break
|
||||
}
|
||||
|
||||
static void BreakpointProlog(BREAKPOINT & bp, bool breakCondition, bool logCondition, bool commandCondition)
|
||||
{
|
||||
// update GUI
|
||||
if(breakCondition)
|
||||
{
|
||||
GuiSetDebugState(paused);
|
||||
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
}
|
||||
|
||||
// plugin interaction
|
||||
lock(WAITID_RUN);
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
pauseInfo.reserved = nullptr;
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
PLUG_CB_BREAKPOINT bpInfo;
|
||||
BRIDGEBP bridgebp;
|
||||
bpInfo.breakpoint = &bridgebp;
|
||||
memset(&bpInfo, 0, sizeof(bpInfo));
|
||||
BpToBridge(&bp, &bridgebp);
|
||||
plugincbcall(CB_BREAKPOINT, &bpInfo);
|
||||
|
||||
if(*bp.logText && logCondition) //log
|
||||
{
|
||||
dprintf("%s\n", stringformatinline(bp.logText).c_str());
|
||||
}
|
||||
if(*bp.commandText && commandCondition) //command
|
||||
{
|
||||
//TODO: commands like run/step etc will fuck up your shit
|
||||
DbgCmdExec(bp.commandText);
|
||||
}
|
||||
if(breakCondition) //break the debugger
|
||||
{
|
||||
SetForegroundWindow(GuiGetWindowHandle());
|
||||
bSkipExceptions = false;
|
||||
}
|
||||
else //resume immediately
|
||||
unlock(WAITID_RUN);
|
||||
|
||||
//wait until the user resumes
|
||||
wait(WAITID_RUN);
|
||||
}
|
||||
|
||||
static void cbGenericBreakpoint(BP_TYPE bptype, void* ExceptionAddress = nullptr)
|
||||
{
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
BREAKPOINT* bpPtr;
|
||||
BREAKPOINT bp;
|
||||
BRIDGEBP pluginBp;
|
||||
PLUG_CB_BREAKPOINT bpInfo;
|
||||
ULONG_PTR CIP;
|
||||
duint condition = 1;
|
||||
memset(&bpInfo, 0, sizeof(bpInfo));
|
||||
CIP = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
auto CIP = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
BREAKPOINT* bpPtr = nullptr;
|
||||
SHARED_ACQUIRE(LockBreakpoints);
|
||||
bpPtr = BpInfoFromAddr(BPNORMAL, CIP);
|
||||
if(!(bpPtr && bpPtr->enabled))
|
||||
dputs("Breakpoint reached not in list!");
|
||||
else
|
||||
switch(bptype)
|
||||
{
|
||||
// increment hit count
|
||||
InterlockedIncrement(&bpPtr->hitcount);
|
||||
// condition eval
|
||||
bp = *bpPtr;
|
||||
SHARED_RELEASE();
|
||||
bp.addr += ModBaseFromAddr(CIP);
|
||||
//setBpActive(bp);
|
||||
|
||||
//if(bp.type == BPHARDWARE) //TODO: properly implement this (check debug registers)
|
||||
// bp.active = true;
|
||||
//else
|
||||
bp.active = MemIsValidReadPtr(bp.addr);
|
||||
|
||||
if(bp.condition[0] != 0)
|
||||
{
|
||||
if(*(uint16*)bp.condition == 0x30) // short curcit for condition "0"
|
||||
condition = 0;
|
||||
else
|
||||
valfromstring(bp.condition, &condition); // if this fails, condition remains 1
|
||||
if(bp.fastResume && condition == 0) // fast resume : ignore GUI/Script/Plugin/Singleshoot/Other
|
||||
return;
|
||||
}
|
||||
if(bp.logText[0] == 0 && condition != 0)
|
||||
{
|
||||
printSoftBpInfo(bp);
|
||||
} // else: BreakpointProlog outputs the log.
|
||||
if(bp.singleshoot)
|
||||
BpDelete(bp.addr, BPNORMAL);
|
||||
BpToBridge(&bp, &pluginBp);
|
||||
bpInfo.breakpoint = &pluginBp;
|
||||
case BPNORMAL:
|
||||
bpPtr = BpInfoFromAddr(bptype, CIP);
|
||||
break;
|
||||
case BPHARDWARE:
|
||||
bpPtr = BpInfoFromAddr(bptype, duint(ExceptionAddress));
|
||||
break;
|
||||
case BPMEMORY:
|
||||
bpPtr = BpInfoFromAddr(bptype, MemFindBaseAddr(duint(ExceptionAddress), nullptr, true));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
BreakpointProlog(condition, bp, bpInfo);
|
||||
if(!(bpPtr && bpPtr->enabled)) //invalid / disabled breakpoint hit (most likely a bug)
|
||||
{
|
||||
dputs("Breakpoint reached not in list!");
|
||||
GuiSetDebugState(paused);
|
||||
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
//lock
|
||||
lock(WAITID_RUN);
|
||||
SetForegroundWindow(GuiGetWindowHandle());
|
||||
bSkipExceptions = false;
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
pauseInfo.reserved = nullptr;
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
wait(WAITID_RUN);
|
||||
return;
|
||||
}
|
||||
|
||||
// increment hit count
|
||||
InterlockedIncrement(&bpPtr->hitcount);
|
||||
|
||||
auto bp = *bpPtr;
|
||||
SHARED_RELEASE();
|
||||
bp.addr += ModBaseFromAddr(CIP);
|
||||
bp.active = true; //a breakpoint that has been hit is active
|
||||
|
||||
//get condition values
|
||||
bool breakCondition;
|
||||
bool logCondition;
|
||||
bool commandCondition;
|
||||
getConditionValues(bp, breakCondition, logCondition, commandCondition);
|
||||
|
||||
if(breakCondition)
|
||||
{
|
||||
if(bp.singleshoot)
|
||||
BpDelete(bp.addr, bptype);
|
||||
switch(bptype)
|
||||
{
|
||||
case BPNORMAL:
|
||||
printSoftBpInfo(bp);
|
||||
break;
|
||||
case BPHARDWARE:
|
||||
printHwBpInfo(bp);
|
||||
break;
|
||||
case BPMEMORY:
|
||||
printMemBpInfo(bp, ExceptionAddress);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(bp.fastResume) // fast resume: ignore GUI/Script/Plugin/Other if the debugger would not break
|
||||
return;
|
||||
|
||||
BreakpointProlog(bp, breakCondition, logCondition, commandCondition);
|
||||
}
|
||||
|
||||
void cbUserBreakpoint()
|
||||
{
|
||||
cbGenericBreakpoint(BPNORMAL);
|
||||
}
|
||||
|
||||
void cbHardwareBreakpoint(void* ExceptionAddress)
|
||||
{
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
BREAKPOINT* bpPtr;
|
||||
BREAKPOINT bp;
|
||||
BRIDGEBP pluginBp;
|
||||
PLUG_CB_BREAKPOINT bpInfo;
|
||||
ULONG_PTR CIP;
|
||||
duint condition = 1;
|
||||
memset(&bpInfo, 0, sizeof(bpInfo));
|
||||
CIP = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
SHARED_ACQUIRE(LockBreakpoints);
|
||||
bpPtr = BpInfoFromAddr(BPHARDWARE, (duint)ExceptionAddress);
|
||||
if(!(bpPtr && bpPtr->enabled))
|
||||
dputs("Hardware breakpoint reached not in list!");
|
||||
else
|
||||
{
|
||||
// increment hit count
|
||||
InterlockedIncrement(&bpPtr->hitcount);
|
||||
// condition eval
|
||||
bp = *bpPtr;
|
||||
SHARED_RELEASE();
|
||||
bp.addr += ModBaseFromAddr(CIP);
|
||||
//setBpActive(bp);
|
||||
|
||||
//if(bp.type == BPHARDWARE) //TODO: properly implement this (check debug registers)
|
||||
bp.active = true;
|
||||
//else
|
||||
// bp.active = MemIsValidReadPtr(bp.addr);
|
||||
|
||||
if(bp.condition[0] != 0)
|
||||
{
|
||||
if(*(uint16*)bp.condition == 0x30) // short curcit for condition "0"
|
||||
condition = 0;
|
||||
else
|
||||
valfromstring(bp.condition, &condition); // if this fails, condition remains 1
|
||||
if(bp.fastResume && condition == 0) // fast resume : ignore GUI/Script/Plugin/Singleshoot/Other
|
||||
return;
|
||||
}
|
||||
if(bp.logText[0] == 0 && condition != 0)
|
||||
{
|
||||
printHwBpInfo(bp);
|
||||
} // else: BreakpointProlog outputs the log.
|
||||
if(bp.singleshoot)
|
||||
BpDelete(bp.addr, BPHARDWARE);
|
||||
BpToBridge(&bp, &pluginBp);
|
||||
bpInfo.breakpoint = &pluginBp;
|
||||
}
|
||||
BreakpointProlog(condition, bp, bpInfo);
|
||||
cbGenericBreakpoint(BPHARDWARE, ExceptionAddress);
|
||||
}
|
||||
|
||||
void cbMemoryBreakpoint(void* ExceptionAddress)
|
||||
{
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
BREAKPOINT bp;
|
||||
BRIDGEBP pluginBp;
|
||||
PLUG_CB_BREAKPOINT bpInfo;
|
||||
duint size;
|
||||
duint base = MemFindBaseAddr((duint)ExceptionAddress, &size, true);
|
||||
ULONG_PTR CIP;
|
||||
duint condition = 1;
|
||||
memset(&bpInfo, 0, sizeof(bpInfo));
|
||||
CIP = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
SHARED_ACQUIRE(LockBreakpoints);
|
||||
auto bpPtr = BpInfoFromAddr(BPMEMORY, base);
|
||||
if(!(bpPtr && bpPtr->enabled))
|
||||
dputs("Memory breakpoint reached not in list!");
|
||||
else
|
||||
{
|
||||
// increment hit count
|
||||
InterlockedIncrement(&bpPtr->hitcount);
|
||||
// condition eval
|
||||
bp = *bpPtr;
|
||||
SHARED_RELEASE();
|
||||
bp.addr += ModBaseFromAddr(CIP);
|
||||
//setBpActive(bp);
|
||||
|
||||
//if(bp.type == BPHARDWARE) //TODO: properly implement this (check debug registers)
|
||||
// bp.active = true;
|
||||
//else
|
||||
bp.active = MemIsValidReadPtr(bp.addr);
|
||||
|
||||
if(bp.condition[0] != 0)
|
||||
{
|
||||
if(*(uint16*)bp.condition == 0x30) // short curcit for condition "0"
|
||||
condition = 0;
|
||||
else
|
||||
valfromstring(bp.condition, &condition); // if this fails, condition remains 1
|
||||
if(bp.fastResume && condition == 0) // fast resume : ignore GUI/Script/Plugin/Singleshoot/Other
|
||||
return;
|
||||
}
|
||||
if(bp.logText[0] == 0 && condition != 0)
|
||||
{
|
||||
printMemBpInfo(bp, ExceptionAddress);
|
||||
} // else: BreakpointProlog outputs the log.
|
||||
BpToBridge(&bp, &pluginBp);
|
||||
bpInfo.breakpoint = &pluginBp;
|
||||
}
|
||||
if(bp.singleshoot)
|
||||
BpDelete(bp.addr, BPMEMORY); //delete from breakpoint list
|
||||
BreakpointProlog(condition, bp, bpInfo);
|
||||
cbGenericBreakpoint(BPMEMORY, ExceptionAddress);
|
||||
}
|
||||
|
||||
void cbLibrarianBreakpoint(void* lpData)
|
||||
|
|
|
|||
|
|
@ -115,7 +115,4 @@ extern char szSymbolCachePath[MAX_PATH];
|
|||
extern bool bUndecorateSymbolNames;
|
||||
extern bool bEnableSourceDebugging;
|
||||
|
||||
//private
|
||||
void BreakpointProlog(duint condition, BREAKPOINT & bp, PLUG_CB_BREAKPOINT & bpInfo);
|
||||
|
||||
#endif // _DEBUGGER_H
|
||||
|
|
|
|||
|
|
@ -445,8 +445,7 @@ CMDRESULT cbDebugDisableBPX(int argc, char* argv[])
|
|||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
CMDRESULT cbDebugSetBPXConditionCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
static CMDRESULT cbDebugSetBPXTextCommon(BP_TYPE Type, int argc, char* argv[], const char* description, std::function<bool(duint, BP_TYPE, const char*)> setFunction)
|
||||
{
|
||||
BREAKPOINT bp;
|
||||
if(argc < 2)
|
||||
|
|
@ -454,123 +453,94 @@ CMDRESULT cbDebugSetBPXConditionCommon(BP_TYPE Type, int argc, char* argv[])
|
|||
dprintf("not enough arguments!\n");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else if(argc == 2)
|
||||
auto value = "";
|
||||
if(argc > 2)
|
||||
value = argv[2];
|
||||
|
||||
if(!BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
if(BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
if(!BpSetCondition(bp.addr, Type, ""))
|
||||
{
|
||||
dprintf("Can't set condition on breakpoint \"%s\"\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf("No such breakpoint \"%s\"\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dprintf("No such breakpoint \"%s\"\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else
|
||||
if(!setFunction(bp.addr, Type, value))
|
||||
{
|
||||
if(BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
BpSetCondition(bp.addr, Type, argv[2]);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf("No such breakpoint \"%s\"\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dprintf("Can't set %s on breakpoint \"%s\"\n", description, argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dprintf("%s set to \"%s\"!\n", description, value);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXConditionCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXTextCommon(Type, argc, argv, "break condition", BpSetBreakCondition);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXLogCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
BREAKPOINT bp;
|
||||
if(argc < 2)
|
||||
{
|
||||
dprintf("not enough arguments!\n");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else if(argc == 2)
|
||||
{
|
||||
if(BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
if(!(BpSetLogText(bp.addr, Type, "")))
|
||||
{
|
||||
dprintf("Can't set logging text on breakpoint \"%s\"\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf("No such breakpoint \"%s\"\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
BpSetLogText(bp.addr, Type, argv[2]);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf("No such breakpoint \"%s\"\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
return cbDebugSetBPXTextCommon(Type, argc, argv, "logging text", BpSetLogText);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXLogConditionCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXTextCommon(Type, argc, argv, "logging condition", BpSetLogCondition);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXCommandCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
BREAKPOINT bp;
|
||||
return cbDebugSetBPXTextCommon(Type, argc, argv, "command on hit", BpSetCommandText);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXCommandConditionCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXTextCommon(Type, argc, argv, "command condition", BpSetCommandCondition);
|
||||
}
|
||||
|
||||
static CMDRESULT cbDebugGetBPXHitCountCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dprintf("not enough arguments!\n");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else if(argc == 2)
|
||||
BREAKPOINT bp;
|
||||
if(!BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
if(BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
if(!BpSetHitCommand(bp.addr, Type, ""))
|
||||
{
|
||||
dprintf("Can't set command on hit on breakpoint \"%s\"", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf("No such breakpoint \"%s\"\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
if(!(BpSetHitCommand(bp.addr, Type, argv[2])))
|
||||
{
|
||||
dprintf("Can't set command on hit on breakpoint \"%s\"", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf("No such breakpoint \"%s\"\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dprintf("No such breakpoint \"%s\"\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
varset("$result", bp.hitcount, false);
|
||||
return STATUS_CONTINUE;
|
||||
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugGetBPXHitCountCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
static CMDRESULT cbDebugResetBPXHitCountCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dprintf("not enough arguments!\n");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint value = 0;
|
||||
if(argc > 2)
|
||||
if(!valfromstring(argv[2], &value, false))
|
||||
return STATUS_ERROR;
|
||||
BREAKPOINT bp;
|
||||
if(!BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
dprintf("No such breakpoint \"%s\"\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!BpResetHitCount(bp.addr, Type, (uint32)value))
|
||||
{
|
||||
dprintf("Can't set hit count on breakpoint \"%s\"", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
|
||||
}
|
||||
|
||||
static CMDRESULT cbDebugSetBPXFastResumeCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
BREAKPOINT bp;
|
||||
if(argc < 2)
|
||||
|
|
@ -578,129 +548,25 @@ CMDRESULT cbDebugGetBPXHitCountCommon(BP_TYPE Type, int argc, char* argv[])
|
|||
dprintf("not enough arguments!\n");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else if(argc == 2)
|
||||
{
|
||||
duint result;
|
||||
if(BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
//result = BpGetHitCount(bp.addr, bp.type);
|
||||
result = bp.hitcount; // improving performance
|
||||
varset("$result", result, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf("No such breakpoint \"%s\"\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf("Too much arguments!\n");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugResetBPXHitCountCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
BREAKPOINT bp;
|
||||
if(argc < 2)
|
||||
{
|
||||
dprintf("not enough arguments!\n");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else if(argc == 2)
|
||||
{
|
||||
duint result;
|
||||
if(BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
result = BpResetHitCount(bp.addr, bp.type, 0);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf("No such breakpoint \"%s\"\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
auto fastResume = true;
|
||||
if(argc > 2)
|
||||
{
|
||||
duint value;
|
||||
if(!(valfromstring(argv[2], &value)))
|
||||
{
|
||||
dprintf("Invalid expression \"%1\"", argv[2]);
|
||||
}
|
||||
if(BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
if(!(BpResetHitCount(bp.addr, Type, (uint32)value)))
|
||||
{
|
||||
dprintf("Can't set command on hit on breakpoint \"%s\"", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf("No such breakpoint \"%s\"\n", argv[1]);
|
||||
if(!valfromstring(argv[2], &value, false))
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
fastResume = value != 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CMDRESULT cbDebugSetBPXFastResumeCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
BREAKPOINT bp;
|
||||
if(argc < 2)
|
||||
if(!BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
dprintf("not enough arguments!\n");
|
||||
dprintf("No such breakpoint \"%s\"\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else if(argc == 2)
|
||||
if(!BpSetFastResume(bp.addr, Type, fastResume))
|
||||
{
|
||||
duint value;
|
||||
if(BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
if(!valfromstring(argv[2], &value))
|
||||
{
|
||||
dprintf("Invalid expression \"%1\"", argv[2]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!(BpSetFastResume(bp.addr, Type, true)))
|
||||
{
|
||||
dprintf("Can't set fast resume on breakpoint \"%1\"", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf("No such breakpoint \"%s\"\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
duint result;
|
||||
if(!(valfromstring(argv[2], &result)))
|
||||
{
|
||||
dprintf("Invalid expression \"%1\"", argv[2]);
|
||||
}
|
||||
if(BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
if(!(BpSetFastResume(bp.addr, Type, result != 0)))
|
||||
{
|
||||
dprintf("Can't set fast resume on breakpoint \"%1\"", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf("No such breakpoint \"%s\"\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dprintf("Can't set fast resume on breakpoint \"%1\"", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXCondition(int argc, char* argv[])
|
||||
|
|
@ -713,11 +579,21 @@ CMDRESULT cbDebugSetBPXLog(int argc, char* argv[])
|
|||
return cbDebugSetBPXLogCommon(BPNORMAL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXLogCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXLogConditionCommon(BPNORMAL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXCommand(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXCommandCommon(BPNORMAL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXCommandCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXCommandConditionCommon(BPNORMAL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXFastResume(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXFastResumeCommon(BPNORMAL, argc, argv);
|
||||
|
|
@ -743,11 +619,21 @@ CMDRESULT cbDebugSetBPXHardwareLog(int argc, char* argv[])
|
|||
return cbDebugSetBPXLogCommon(BPHARDWARE, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXHardwareLogCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXLogConditionCommon(BPHARDWARE, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXHardwareCommand(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXCommandCommon(BPHARDWARE, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXHardwareCommandCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXCommandConditionCommon(BPHARDWARE, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXHardwareFastResume(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXFastResumeCommon(BPHARDWARE, argc, argv);
|
||||
|
|
@ -773,11 +659,21 @@ CMDRESULT cbDebugSetBPXMemoryLog(int argc, char* argv[])
|
|||
return cbDebugSetBPXLogCommon(BPMEMORY, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXMemoryLogCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXLogConditionCommon(BPMEMORY, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXMemoryCommand(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXCommandCommon(BPMEMORY, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXMemoryCommandCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXCommandConditionCommon(BPMEMORY, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugResetBPXMemoryHitCount(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXFastResumeCommon(BPMEMORY, argc, argv);
|
||||
|
|
@ -792,6 +688,7 @@ CMDRESULT cbDebugGetBPXMemoryHitCount(int argc, char* argv[])
|
|||
{
|
||||
return cbDebugGetBPXHitCountCommon(BPMEMORY, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetHardwareBreakpoint(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@ CMDRESULT cbDebugEnableBPX(int argc, char* argv[]);
|
|||
CMDRESULT cbDebugDisableBPX(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXCondition(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXLog(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXLogCondition(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXCommand(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXCommandCondition(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugGetBPXHitCount(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXFastResume(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugResetBPXHitCount(int argc, char* argv[]);
|
||||
|
|
@ -26,7 +28,9 @@ CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[]);
|
|||
CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXHardwareCondition(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXHardwareLog(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXHardwareLogCondition(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXHardwareCommand(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXHardwareCommandCondition(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugGetBPXHardwareHitCount(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXHardwareFastResume(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugResetBPXHardwareHitCount(int argc, char* argv[]);
|
||||
|
|
@ -36,7 +40,9 @@ CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[]);
|
|||
CMDRESULT cbDebugDisableMemoryBreakpoint(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXMemoryCondition(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXMemoryLog(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXMemoryLogCondition(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXMemoryCommand(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXMemoryCommandCondition(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugGetBPXMemoryHitCount(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetBPXMemoryFastResume(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugResetBPXMemoryHitCount(int argc, char* argv[]);
|
||||
|
|
|
|||
|
|
@ -124,21 +124,29 @@ static void registercommands()
|
|||
dbgcmdnew("DeleteMemoryBPX\1membpc\1bpmc", cbDebugDeleteMemoryBreakpoint, true); //delete memory breakpoint
|
||||
dbgcmdnew("EnableMemoryBreakpoint\1membpe\1bpme", cbDebugEnableMemoryBreakpoint, true); //enable memory breakpoint
|
||||
dbgcmdnew("DisableMemoryBreakpoint\1membpd\1bpmd", cbDebugDisableMemoryBreakpoint, true); //enable memory breakpoint
|
||||
dbgcmdnew("SetBreakpointCondition\1bpcond", cbDebugSetBPXCondition, true); //set breakpoint condition
|
||||
dbgcmdnew("SetBreakpointLog\1bplog", cbDebugSetBPXLog, true); //set breakpoint log
|
||||
|
||||
//breakpoints (conditional)
|
||||
dbgcmdnew("SetBreakpointCondition\1bpcond", cbDebugSetBPXCondition, true); //set breakpoint breakCondition
|
||||
dbgcmdnew("SetBreakpointLog\1bplog", cbDebugSetBPXLog, true); //set breakpoint logText
|
||||
dbgcmdnew("SetBreakpointLogCondition\1bplogcondition", cbDebugSetBPXLogCondition, true); //set breakpoint logCondition
|
||||
dbgcmdnew("SetBreakpointCommand", cbDebugSetBPXCommand, true); //set breakpoint command on hit
|
||||
dbgcmdnew("SetBreakpointCommandCondition", cbDebugSetBPXCommandCondition, true); //set breakpoint commandCondition
|
||||
dbgcmdnew("SetBreakpointFastResume", cbDebugSetBPXFastResume, true); //set breakpoint fast resume
|
||||
dbgcmdnew("GetBreakpointHitCount", cbDebugGetBPXHitCount, true); //get breakpoint hit count
|
||||
dbgcmdnew("ResetBreakpointHitCount", cbDebugResetBPXHitCount, true); //reset breakpoint hit count
|
||||
dbgcmdnew("SetHardwareBreakpointCondition\1bphwcond", cbDebugSetBPXHardwareCondition, true); //set breakpoint condition
|
||||
dbgcmdnew("SetHardwareBreakpointLog\1bphwlog", cbDebugSetBPXHardwareLog, true); //set breakpoint log
|
||||
dbgcmdnew("SetHardwareBreakpointCondition\1bphwcond", cbDebugSetBPXHardwareCondition, true); //set breakpoint breakCondition
|
||||
dbgcmdnew("SetHardwareBreakpointLog\1bphwlog", cbDebugSetBPXHardwareLog, true); //set breakpoint logText
|
||||
dbgcmdnew("SetHardwareBreakpointLogCondition\1bphwlogcondition", cbDebugSetBPXHardwareLogCondition, true); //set breakpoint logText
|
||||
dbgcmdnew("SetHardwareBreakpointCommand", cbDebugSetBPXHardwareCommand, true); //set breakpoint command on hit
|
||||
dbgcmdnew("SetHardwareBreakpointCommandCondition", cbDebugSetBPXHardwareCommandCondition, true); //set breakpoint commandCondition
|
||||
dbgcmdnew("SetHardwareBreakpointFastResume", cbDebugSetBPXHardwareFastResume, true); //set breakpoint fast resume
|
||||
dbgcmdnew("GetHardwareBreakpointHitCount", cbDebugGetBPXHardwareHitCount, true); //get breakpoint hit count
|
||||
dbgcmdnew("ResetHardwareBreakpointHitCount", cbDebugResetBPXHardwareHitCount, true); //reset breakpoint hit count
|
||||
dbgcmdnew("SetMemoryBreakpointCondition\1bpmcond", cbDebugSetBPXMemoryCondition, true); //set breakpoint condition
|
||||
dbgcmdnew("SetMemoryBreakpointCondition\1bpmcond", cbDebugSetBPXMemoryCondition, true); //set breakpoint breakCondition
|
||||
dbgcmdnew("SetMemoryBreakpointLog\1bpmlog", cbDebugSetBPXMemoryLog, true); //set breakpoint log
|
||||
dbgcmdnew("SetMemoryBreakpointLogCondition\1bpmlogcondition", cbDebugSetBPXMemoryLogCondition, true); //set breakpoint logCondition
|
||||
dbgcmdnew("SetMemoryBreakpointCommand", cbDebugSetBPXMemoryCommand, true); //set breakpoint command on hit
|
||||
dbgcmdnew("SetMemoryBreakpointCommandCondition", cbDebugSetBPXMemoryCommandCondition, true); //set breakpoint commandCondition
|
||||
dbgcmdnew("SetMemoryBreakpointFastResume", cbDebugSetBPXMemoryFastResume, true); //set breakpoint fast resume
|
||||
dbgcmdnew("SetMemoryGetBreakpointHitCount", cbDebugGetBPXMemoryHitCount, true); //get breakpoint hit count
|
||||
dbgcmdnew("ResetMemoryBreakpointHitCount", cbDebugResetBPXMemoryHitCount, true); //reset breakpoint hit count
|
||||
|
|
|
|||
|
|
@ -116,10 +116,10 @@ void BreakpointsView::reloadData()
|
|||
mHardBPTable->setCellContent(wI, 3, tr("Disabled"));
|
||||
|
||||
mHardBPTable->setCellContent(wI, 4, QString("%1").arg(wBPList.bp[wI].hitCount));
|
||||
mHardBPTable->setCellContent(wI, 5, QString().fromUtf8(wBPList.bp[wI].log));
|
||||
mHardBPTable->setCellContent(wI, 6, QString().fromUtf8(wBPList.bp[wI].condition));
|
||||
mHardBPTable->setCellContent(wI, 5, QString().fromUtf8(wBPList.bp[wI].logText));
|
||||
mHardBPTable->setCellContent(wI, 6, QString().fromUtf8(wBPList.bp[wI].breakCondition));
|
||||
mHardBPTable->setCellContent(wI, 7, wBPList.bp[wI].fastResume ? "X" : "");
|
||||
mHardBPTable->setCellContent(wI, 8, QString().fromUtf8(wBPList.bp[wI].hitCmd));
|
||||
mHardBPTable->setCellContent(wI, 8, QString().fromUtf8(wBPList.bp[wI].commandText));
|
||||
|
||||
char text[MAX_COMMENT_SIZE] = "";
|
||||
if(DbgGetCommentAt(wBPList.bp[wI].addr, text))
|
||||
|
|
@ -162,10 +162,10 @@ void BreakpointsView::reloadData()
|
|||
mSoftBPTable->setCellContent(wI, 3, tr("Disabled"));
|
||||
|
||||
mSoftBPTable->setCellContent(wI, 4, QString("%1").arg(wBPList.bp[wI].hitCount));
|
||||
mSoftBPTable->setCellContent(wI, 5, QString().fromUtf8(wBPList.bp[wI].log));
|
||||
mSoftBPTable->setCellContent(wI, 6, QString().fromUtf8(wBPList.bp[wI].condition));
|
||||
mSoftBPTable->setCellContent(wI, 5, QString().fromUtf8(wBPList.bp[wI].logText));
|
||||
mSoftBPTable->setCellContent(wI, 6, QString().fromUtf8(wBPList.bp[wI].breakCondition));
|
||||
mSoftBPTable->setCellContent(wI, 7, wBPList.bp[wI].fastResume ? "X" : "");
|
||||
mSoftBPTable->setCellContent(wI, 8, QString().fromUtf8(wBPList.bp[wI].hitCmd));
|
||||
mSoftBPTable->setCellContent(wI, 8, QString().fromUtf8(wBPList.bp[wI].commandText));
|
||||
|
||||
char comment[MAX_COMMENT_SIZE] = "";
|
||||
if(DbgGetCommentAt(wBPList.bp[wI].addr, comment))
|
||||
|
|
@ -207,10 +207,10 @@ void BreakpointsView::reloadData()
|
|||
mMemBPTable->setCellContent(wI, 3, tr("Disabled"));
|
||||
|
||||
mMemBPTable->setCellContent(wI, 4, QString("%1").arg(wBPList.bp[wI].hitCount));
|
||||
mMemBPTable->setCellContent(wI, 5, QString().fromUtf8(wBPList.bp[wI].log));
|
||||
mMemBPTable->setCellContent(wI, 6, QString().fromUtf8(wBPList.bp[wI].condition));
|
||||
mMemBPTable->setCellContent(wI, 5, QString().fromUtf8(wBPList.bp[wI].logText));
|
||||
mMemBPTable->setCellContent(wI, 6, QString().fromUtf8(wBPList.bp[wI].breakCondition));
|
||||
mMemBPTable->setCellContent(wI, 7, wBPList.bp[wI].fastResume ? "X" : "");
|
||||
mMemBPTable->setCellContent(wI, 8, QString().fromUtf8(wBPList.bp[wI].hitCmd));
|
||||
mMemBPTable->setCellContent(wI, 8, QString().fromUtf8(wBPList.bp[wI].commandText));
|
||||
|
||||
char comment[MAX_COMMENT_SIZE] = "";
|
||||
if(DbgGetCommentAt(wBPList.bp[wI].addr, comment))
|
||||
|
|
|
|||
Loading…
Reference in New Issue