关于c ++:MinGW SEH和MinGW SJLJ有什么区别?

What is the difference between MinGW SEH and MinGW SJLJ?

我才刚刚开始学习C并现在安装QT x64(在这里形成表格:http://tver-soft.org/qt64)。 我有两个安装选项:MinGW 4.9.2 SEHMinGW 4.9.2 SJLJ
问题:哪个安装更好,为什么安装?

我读过sjlj vs dwarf vs seh有什么区别? 和https://wiki.qt.io/MinGW-64-bit#Exception_handling:_SJLJ.2C_DWARF.2C_and_SEH,但一无所知(C和Compiller语言的新手)。


SJLJ和SEH是两个不同的异常处理系统。

对于特定的差异,您已经看到的资源涵盖了所有内容。

但是,关于哪一种更好安装,除非您知道需要SEH,否则请随SJLJ一起去。

2019更新:在现代系统上,没有理由使用SJLJ,因此上述建议可能应该被翻转。 SEH现在更加普遍。归根结底,这并不重要,因为在两者之间切换很容易。

J

SJLJ在各种体系结构中得到了更广泛的支持,并且更加健壮。同样,可以通过使用其他异常处理系统的库(包括C库)引发SJLJ异常。但是,它会降低性能。

SEH

SEH效率更高(不会降低性能),但是不幸的是,它没有得到很好的支持。当通过不使用SEH的库抛出SEH异常时,会导致发生不好的事情。

就您的代码而言,没有真正的区别。如果需要,您以后总是可以切换编译器。


我发现MinGW-w64中SJLJ和SEH异常处理之间的区别:在运行时至少执行了一个try {}块,由signal()函数设置的C信号处理程序在SJLJ版本中不起作用。由于似乎没有在任何地方描述此问题,因此将其记录在案。

以下示例(test_signals.cpp)演示了这一点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// This sample demonstrates how try {} block disables handler set by signal()
// on MinGW-w64 with GCC SJLJ build
#include <signal.h>
#include <iostream>

int izero = 0;

static void SIGWntHandler (int signum)//sub_code)
{
  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
"
;
  if (signal (SIGFPE, (void(*)(int))SIGWntHandler) == SIG_ERR)
    std::cout <<"signal(OSD::SetSignal) error
"
;
  if (signal (SIGILL, (void(*)(int))SIGWntHandler) == SIG_ERR)
    std::cout <<"signal(OSD::SetSignal) error
"
;

  // this try block disables signal handler...
  try { std::cout <<"In try block" << std::endl; } catch(char*) {}

  std::cout <<"Doing bad things to cause signal..." << std::endl;
  izero = 1 / izero; // cause integer division by zero
  char* ptrnull = 0;
  ptrnull[0] = '\0'; // cause access violation

  std::cout <<"We are too lucky..." << std::endl;
  return 0;
}

构建:

1
g++ test_signals.cpp -o test_signals.exe

预期输出为:

1
2
3
4
5
Entered main(), arming signal handler...
In try block
Doing bad things to cause signal...
In signal handler, signum = 8
Now exiting...

使用MigGW-w64 SJLJ变体构建时的实际输出为:

1
2
3
Entered main(), arming signal handler...
In try block
Doing bad things to cause signal...

延迟一段时间后,应用程序将以静默方式终止。也就是说,信号处理程序不会被调用。如果try {}块被注释掉,则信号处理程序将被正确调用。

使用MinGW-w64 SEH变体时,它的行为符合预期(调用了信号处理程序)。

我不清楚为什么会发生此问题,因此,如果有人可以提供解释,将不胜感激。