我在MinGW-w64中发现了SJLJ和SEH异常处理之间的一个区别:只要在运行时执行了至少一个try{}块,由signal()函数设置的C信号处理程序在SJLJ版本中就无法工作。由于这个问题似乎没有在任何地方被描述,所以我在这里记录一下。
以下示例(test_signals.cpp)演示了这一点。
#include <signal.h>
#include <iostream>
int izero = 0;
static void SIGWntHandler (int signum)
{
std::cout << "In signal handler, signum = " << signum << std::endl;
std::cout << "Now exiting..." << std::endl;
std::exit(1);
}
int main (void)
{
std::cout << "Entered main(), arming signal handler..." << std::endl;
if (signal (SIGSEGV, (void(*)(int))SIGWntHandler) == SIG_ERR)
std::cout << "signal(OSD::SetSignal) error\n";
if (signal (SIGFPE, (void(*)(int))SIGWntHandler) == SIG_ERR)
std::cout << "signal(OSD::SetSignal) error\n";
if (signal (SIGILL, (void(*)(int))SIGWntHandler) == SIG_ERR)
std::cout << "signal(OSD::SetSignal) error\n";
try { std::cout << "In try block" << std::endl; } catch(char*) {}
std::cout << "Doing bad things to cause signal..." << std::endl;
izero = 1 / izero;
char* ptrnull = 0;
ptrnull[0] = '\0';
std::cout << "We are too lucky..." << std::endl;
return 0;
}
使用以下内容进行构建:
g++ test_signals.cpp -o test_signals.exe
预期输出为:
Entered main(), arming signal handler...
In try block
Doing bad things to cause signal...
In signal handler, signum = 8
Now exiting...
当我使用MigGW-w64 SJLJ变体进行构建时,实际输出结果为:
Entered main(), arming signal handler...
In try block
Doing bad things to cause signal...
应用程序在一段时间后静默终止。也就是说,信号处理程序没有被调用。如果注释掉try{}块,则信号处理程序会被正确调用。
当使用MinGW-w64 SEH变体时,它的行为符合预期(信号处理程序被调用)。
我不清楚为什么会出现这个问题,因此如果有人能够给出解释,我将不胜感激。