DBG+GUI: add transparent exception stepping option
This commit is contained in:
parent
3bad6cb6dc
commit
de2d930d8f
|
@ -391,7 +391,7 @@ bool cbDebugStepOver(int argc, char* argv[])
|
|||
return true;
|
||||
if(skipInt3Stepping(1, argv) && !--steprepeat)
|
||||
return true;
|
||||
StepOver((void*)cbStep);
|
||||
StepOverWrapper((void*)cbStep);
|
||||
// History
|
||||
HistoryClear();
|
||||
dbgsetsteprepeat(false, steprepeat);
|
||||
|
@ -419,7 +419,7 @@ bool cbDebugStepOut(int argc, char* argv[])
|
|||
return true;
|
||||
HistoryClear();
|
||||
mRtrPreviousCSP = GetContextDataEx(hActiveThread, UE_CSP);
|
||||
StepOver((void*)cbRtrStep);
|
||||
StepOverWrapper((void*)cbRtrStep);
|
||||
dbgsetsteprepeat(false, steprepeat);
|
||||
return cbDebugRunInternal(1, argv);
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ static bool cbDebugConditionalTrace(void(*callback)(), bool stepOver, int argc,
|
|||
HistoryClear();
|
||||
|
||||
if(stepOver)
|
||||
StepOver((void*)callback);
|
||||
StepOverWrapper((void*)callback);
|
||||
else
|
||||
StepIntoWow64((void*)callback);
|
||||
return cbDebugRunInternal(1, argv);
|
||||
|
|
|
@ -70,6 +70,8 @@ static char szDebuggeeInitializationScript[MAX_PATH] = "";
|
|||
static WString gInitExe, gInitCmd, gInitDir, gDllLoader;
|
||||
static CookieQuery cookie;
|
||||
static bool bDatabaseLoaded = false;
|
||||
static duint exceptionDispatchAddr = 0;
|
||||
static bool bPausedOnException = false;
|
||||
char szProgramDir[MAX_PATH] = "";
|
||||
char szFileName[MAX_PATH] = "";
|
||||
char szSymbolCachePath[MAX_PATH] = "";
|
||||
|
@ -1166,7 +1168,7 @@ void cbStep()
|
|||
{
|
||||
if(bTraceRecordEnabledDuringTrace)
|
||||
_dbg_dbgtraceexecute(CIP);
|
||||
(bRepeatIn ? StepIntoWow64 : StepOver)((void*)cbStep);
|
||||
(bRepeatIn ? StepIntoWow64 : StepOverWrapper)((void*)cbStep);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1190,7 +1192,7 @@ static void cbRtrFinalStep(bool checkRepeat = false)
|
|||
wait(WAITID_RUN);
|
||||
}
|
||||
else
|
||||
StepOver((void*)cbRtrStep);
|
||||
StepOverWrapper((void*)cbRtrStep);
|
||||
}
|
||||
|
||||
void cbRtrStep()
|
||||
|
@ -1219,15 +1221,15 @@ void cbRtrStep()
|
|||
if(cp.Disassemble(cip, data) && cp.IsRet())
|
||||
cbRtrFinalStep(true);
|
||||
else
|
||||
StepOver((void*)cbRtrStep);
|
||||
StepOverWrapper((void*)cbRtrStep);
|
||||
}
|
||||
else
|
||||
{
|
||||
StepOver((void*)cbRtrStep);
|
||||
StepOverWrapper((void*)cbRtrStep);
|
||||
}
|
||||
}
|
||||
else
|
||||
StepOver((void*)cbRtrStep);
|
||||
StepOverWrapper((void*)cbRtrStep);
|
||||
}
|
||||
|
||||
static void cbTraceUniversalConditionalStep(duint cip, bool bStepInto, void(*callback)(), bool forceBreakTrace)
|
||||
|
@ -1276,7 +1278,7 @@ static void cbTraceUniversalConditionalStep(duint cip, bool bStepInto, void(*cal
|
|||
_dbg_dbgtraceexecute(cip);
|
||||
if(switchCondition) //switch (invert) the step type once
|
||||
bStepInto = !bStepInto;
|
||||
(bStepInto ? StepIntoWow64 : StepOver)((void*)callback);
|
||||
(bStepInto ? StepIntoWow64 : StepOverWrapper)((void*)callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1709,9 +1711,13 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
|
|||
}
|
||||
}
|
||||
|
||||
//process cookie
|
||||
if(settingboolget("Misc", "QueryProcessCookie") && ModNameFromAddr(duint(base), modname, true) && scmp(modname, "ntdll.dll"))
|
||||
cookie.HandleNtdllLoad();
|
||||
if(ModNameFromAddr(duint(base), modname, true) && scmp(modname, "ntdll.dll"))
|
||||
{
|
||||
if(settingboolget("Misc", "QueryProcessCookie"))
|
||||
cookie.HandleNtdllLoad();
|
||||
if(settingboolget("Misc", "TransparentExceptionStepping"))
|
||||
exceptionDispatchAddr = DbgValFromString("ntdll:KiUserExceptionDispatcher");
|
||||
}
|
||||
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "DLL Loaded: %p %s\n"), base, DLLDebugFileName);
|
||||
|
||||
|
@ -1872,7 +1878,9 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
|
|||
BREAKPOINT bp;
|
||||
if(BpGet(ExceptionCode, BPEXCEPTION, nullptr, &bp) && bp.enabled && ((bp.titantype == 1 && ExceptionData->dwFirstChance) || (bp.titantype == 2 && !ExceptionData->dwFirstChance) || bp.titantype == 3))
|
||||
{
|
||||
bPausedOnException = true;
|
||||
cbGenericBreakpoint(BPEXCEPTION, ExceptionData);
|
||||
bPausedOnException = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1902,6 +1910,7 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
|
|||
DebugUpdateGuiSetStateAsync(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
//lock
|
||||
lock(WAITID_RUN);
|
||||
bPausedOnException = true;
|
||||
// Plugin callback
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo = { nullptr };
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
|
@ -1909,6 +1918,7 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
|
|||
dbgsetskipexceptions(false);
|
||||
plugincbcall(CB_EXCEPTION, &callbackInfo);
|
||||
wait(WAITID_RUN);
|
||||
bPausedOnException = false;
|
||||
return;
|
||||
}
|
||||
SetContextDataEx(hActiveThread, UE_CIP, (duint)ExceptionData->ExceptionRecord.ExceptionAddress);
|
||||
|
@ -1957,6 +1967,7 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
|
|||
DebugUpdateGuiSetStateAsync(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
//lock
|
||||
lock(WAITID_RUN);
|
||||
bPausedOnException = true;
|
||||
// Plugin callback
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo = { nullptr };
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
|
@ -1964,6 +1975,7 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
|
|||
dbgsetskipexceptions(false);
|
||||
plugincbcall(CB_EXCEPTION, &callbackInfo);
|
||||
wait(WAITID_RUN);
|
||||
bPausedOnException = false;
|
||||
}
|
||||
|
||||
static void cbDebugEvent(DEBUG_EVENT* DebugEvent)
|
||||
|
@ -2830,7 +2842,26 @@ void StepIntoWow64(LPVOID traceCallBack)
|
|||
}
|
||||
}
|
||||
#endif //_WIN64
|
||||
StepInto(traceCallBack);
|
||||
if(bPausedOnException && exceptionDispatchAddr && !IsBPXEnabled(exceptionDispatchAddr))
|
||||
{
|
||||
SetBPX(exceptionDispatchAddr, UE_SINGLESHOOT, traceCallBack);
|
||||
}
|
||||
else
|
||||
{
|
||||
StepInto(traceCallBack);
|
||||
}
|
||||
}
|
||||
|
||||
void StepOverWrapper(LPVOID traceCallBack)
|
||||
{
|
||||
if(bPausedOnException && exceptionDispatchAddr && !IsBPXEnabled(exceptionDispatchAddr))
|
||||
{
|
||||
SetBPX(exceptionDispatchAddr, UE_SINGLESHOOT, traceCallBack);
|
||||
}
|
||||
else
|
||||
{
|
||||
StepOver(traceCallBack);
|
||||
}
|
||||
}
|
||||
|
||||
bool dbgisdepenabled()
|
||||
|
|
|
@ -103,7 +103,8 @@ void cbDetach();
|
|||
bool cbSetModuleBreakpoints(const BREAKPOINT* bp);
|
||||
EXCEPTION_DEBUG_INFO & getLastExceptionInfo();
|
||||
bool dbgrestartadmin();
|
||||
void StepIntoWow64(void* traceCallBack);
|
||||
void StepIntoWow64(LPVOID traceCallBack);
|
||||
void StepOverWrapper(LPVOID traceCallBack);
|
||||
bool dbgisdepenabled();
|
||||
BOOL CALLBACK chkWindowPidCallback(HWND hWnd, LPARAM lParam);
|
||||
BOOL ismainwindow(HWND handle);
|
||||
|
|
|
@ -319,10 +319,12 @@ void SettingsDialog::LoadSettings()
|
|||
GetSettingBool("Misc", "UseLocalHelpFile", &settings.miscUseLocalHelpFile);
|
||||
GetSettingBool("Misc", "QueryProcessCookie", &settings.miscQueryProcessCookie);
|
||||
GetSettingBool("Misc", "QueryWorkingSet", &settings.miscQueryWorkingSet);
|
||||
GetSettingBool("Misc", "TransparentExceptionStepping", &settings.miscTransparentExceptionStepping);
|
||||
ui->chkUtf16LogRedirect->setChecked(settings.miscUtf16LogRedirect);
|
||||
ui->chkUseLocalHelpFile->setChecked(settings.miscUseLocalHelpFile);
|
||||
ui->chkQueryProcessCookie->setChecked(settings.miscQueryProcessCookie);
|
||||
ui->chkQueryWorkingSet->setChecked(settings.miscQueryWorkingSet);
|
||||
ui->chkTransparentExceptionStepping->setChecked(settings.miscTransparentExceptionStepping);
|
||||
}
|
||||
|
||||
void SettingsDialog::SaveSettings()
|
||||
|
@ -424,6 +426,7 @@ void SettingsDialog::SaveSettings()
|
|||
BridgeSettingSetUint("Misc", "UseLocalHelpFile", settings.miscUseLocalHelpFile);
|
||||
BridgeSettingSetUint("Misc", "QueryProcessCookie", settings.miscQueryProcessCookie);
|
||||
BridgeSettingSetUint("Misc", "QueryWorkingSet", settings.miscQueryWorkingSet);
|
||||
BridgeSettingSetUint("Misc", "TransparentExceptionStepping", settings.miscTransparentExceptionStepping);
|
||||
|
||||
BridgeSettingFlush();
|
||||
Config()->load();
|
||||
|
@ -910,3 +913,8 @@ void SettingsDialog::on_chkQueryWorkingSet_toggled(bool checked)
|
|||
{
|
||||
settings.miscQueryWorkingSet = checked;
|
||||
}
|
||||
|
||||
void SettingsDialog::on_chkTransparentExceptionStepping_toggled(bool checked)
|
||||
{
|
||||
settings.miscTransparentExceptionStepping = checked;
|
||||
}
|
||||
|
|
|
@ -97,6 +97,7 @@ private slots:
|
|||
void on_chkUseLocalHelpFile_toggled(bool checked);
|
||||
void on_chkQueryProcessCookie_toggled(bool checked);
|
||||
void on_chkQueryWorkingSet_toggled(bool checked);
|
||||
void on_chkTransparentExceptionStepping_toggled(bool checked);
|
||||
|
||||
private:
|
||||
//enums
|
||||
|
@ -196,6 +197,7 @@ private:
|
|||
bool miscUseLocalHelpFile;
|
||||
bool miscQueryProcessCookie;
|
||||
bool miscQueryWorkingSet;
|
||||
bool miscTransparentExceptionStepping;
|
||||
};
|
||||
|
||||
//variables
|
||||
|
|
|
@ -855,6 +855,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="chkTransparentExceptionStepping">
|
||||
<property name="text">
|
||||
<string>Transparent exception stepping*</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
|
|
Loading…
Reference in New Issue