1
0
Fork 0

DBG+GUI: add transparent exception stepping option

This commit is contained in:
Duncan Ogilvie 2019-08-17 12:19:08 +02:00
parent 3bad6cb6dc
commit de2d930d8f
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
7 changed files with 63 additions and 14 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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()

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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">