(环境:Linux 3.0 / x86_64上的gcc / g ++ 4.6.1 in -std = gnu ++ 0x模式…)
#include <stdlib.h> #include <signal.h> #include <iostream> using namespace std; class SegmentationFault {}; void ThrowSegmentationFault(int) { throw SegmentationFault(); } void ohno(char* x) { *x = 42; } int main() { signal(SIGSEGV, ThrowSegmentationFault); try { ohno(0); } catch (const SegmentationFault&) { cout << "success" << endl; } }
通过使用-fnon-call-exceptions标志编译上述代码 ,它允许SIGSEGV信号处理程序抛出exception,并在运行时打印“成功”。 -fnon-call-exceptions gcc标志的文档如下所示:
生成允许陷印指令抛出exception的代码。 请注意,这需要在任何地方都不存在的平台特定的运行时支持。 而且,它只允许捕获指令抛出exception,即内存引用或浮点指令。 它不允许从任意信号处理程序(如SIGALRM)抛出exception。
我的问题是哪些信号是陷阱指令,哪些不是?
#define SIGHUP 1 #define SIGINT 2 #define SIGQUIT 3 #define SIGILL 4 #define SIGTRAP 5 #define SIGABRT 6 #define SIGIOT 6 #define SIGBUS 7 #define SIGFPE 8 #define SIGKILL 9 #define SIGUSR1 10 #define SIGSEGV 11 #define SIGUSR2 12 #define SIGPIPE 13 #define SIGALRM 14 #define SIGTERM 15 #define SIGSTKFLT 16 #define SIGCHLD 17 #define SIGCONT 18 #define SIGSTOP 19 #define SIGTSTP 20 #define SIGTTIN 21 #define SIGTTOU 22 #define SIGURG 23 #define SIGXCPU 24 #define SIGXFSZ 25 #define SIGVTALRM 26 #define SIGPROF 27 #define SIGWINCH 28 #define SIGIO 29 #define SIGPOLL SIGIO /* #define SIGLOST 29 */ #define SIGPWR 30 #define SIGSYS 31 #define SIGUNUSED 31
SIGILL,SIGTRAP,SIGBUS,SIGFPE,SIGSEGV,SIGSTKFLT是最可能的同步信号(即,由硬件产生的指令尝试做一些无效的结果)。