0

我写了一个 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();
    }

}
4

1 回答 1

0

未捕获 WM_PAINT 访问冲突的答案

实际上只有一些 wm 消息被 SEH 捕获,例如 WM_LBUTTONDOWN 没有被 SEH 捕获。在调用 WndProc 之前删除所有 SEH 处理程序,然后您可以使用 __asm int 3 或 __debugbreak() 来中断应用程序。

    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;
    }
于 2013-10-29T07:36:17.097 回答