首页 > 解决方案 > 未调用由 signal() 指定的处理程序

问题描述

我正在尝试在 Win32/C++ 程序中打印调用堆栈。

这篇文章中,我学到了一种在访问冲突时调用我的处理程序的方法。但是,这似乎只适用于简单的控制台程序。

在我将相同的代码复制到带有消息泵的 win32 程序中后,我的处理程序没有被调用。

我认为钩子安装部分是相同的,唯一的区别是触发访问冲突的邪恶代码不是在处理程序安装后立即调用,而是从处理程序安装中抽出几个消息。

有没有人暗示为什么我的处理程序没有被调用?

让我尝试解释我的代码如下:

void SignalHandler_SegmentViolation(int signal)
{
    StackWalker sw;
    sw.ShowCallstack();
    throw "!Access Violation!";
}
void someFuncionCalledUponButtonClick()
{
    *(int*)0x00 = 5;
}
void myMsgPump()
{
    while(TRUE)
    {
        GetMessage(&msg, NULL, 0, 0);
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst,LPSTR lpszArgs, int nWinMode)
{
    typedef void (*SignalHandlerPointer)(int);

    SignalHandlerPointer previousHandler;
    previousHandler = signal(SIGSEGV , SignalHandler_SegmentViolation);

    try
    {
        myMsgPump();
    }
    catch(char *e)
    {
        printf("Exception Caught: %s\n",e);

        // return control to default handler
        previousHandler(SIGSEGV);
    }
}

标签: c++winapiexceptionsignalshandler

解决方案


在 Windows 上,信号系统及其支持功能是与 POSIX(类似 Unix 的系统,如 Linux 或 macOS)的小型兼容层的一部分。因此,许多 POSIX 标准信号并没有真正实现并且不起作用。

在 Windows 中不起作用的此类信号之一是分段故障信号SIGSEGV

控制台层(CRT)是 WIN32 系统之上的一层,可能实现了某些信号。还有其他 POSIX 兼容系统(例如 Cygwin)也有自己的信号实现。对于直接的 WIN32 程序,没有这种兼容性。


推荐阅读