我编写了一个ASSERT宏,如下所示的代码:
do{
if (true) {
int ret = _DbgCheckMsg(__WSHORT_FILE__, __LINE__, L"haha", L"haha", (const wchar_t*)nullptr);
if (ret == 1) {
TRACEF("called int 3");
__asm int 3;
TRACEF("after called int 3");
} else if (ret == -1)
_DbgAbort();
}
} while (0);
在Visual Studio中使用F5运行时,或者在没有F5但不在wndproc处理程序中运行时,它运行良好,但是如果在没有F5的情况下运行并且在wndproc消息处理程序中运行时,wndproc只是简单地吞下断点异常,就像它对c标准断言函数所做的那样。
但是我需要在没有先附加调试器的 wndproc 消息处理程序中触发 jit 对话框。我该怎么做?
我曾尝试在 SEH 中扭曲 wndproc,但它没有帮助,因为它会闯入异常处理程序而不是在消息处理程序代码处中断。
LRESULT CALLBACK WndProcWrapper(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
__try {
return WndProc(hWnd, message, wParam, lParam);
} __except(GetExceptionCode() == EXCEPTION_BREAKPOINT ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
TRACEF("exception caught");
//LPEXCEPTION_POINTERS pep = GetExceptionInformation();
}
}
捕获WM_PAINT访问冲突的答案
实际上,SEH 只捕获了一些 wm 消息,例如WM_LBUTTONDOWN 没有被 SEH 捕获。在调用 WndProc 之前删除所有 SEH 处理程序,然后您可以使用 int 3 或 __debugbreak() __asm来破坏应用程序。
LRESULT CALLBACK WndProcWrapper(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// get thread information block
NT_TIB* tib;
__asm {
mov EAX, FS:[18h]
mov [tib], EAX
}
// old exception handler list
_EXCEPTION_REGISTRATION_RECORD* old_exception_handler = tib->ExceptionList;
// remove all exception handler with exception of the default handler
while( tib->ExceptionList->Next != (_EXCEPTION_REGISTRATION_RECORD*)-1 ) {
tib->ExceptionList = tib->ExceptionList->Next;
}
LRESULT result = WndProc( hWnd, message, wParam, lParam );
// restore old exception handler
tib->ExceptionList = old_exception_handler;
return result;
}