(环境:Linux 3.0 / x86_64上-std = gnu 0x模式下的gcc / g 4.6.1 …)
#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 信号处理程序引发异常,并且在运行时它将打印“成功”。 -fnon-call-exceptions gcc标志的文档内容如下:
生成允许捕获指令引发异常的代码。请注意,这需要特定于平台的运行时支持,而该支持并非在每个地方都存在。而且,它仅允许陷阱指令引发异常,即内存引用或浮点指令。它不允许从任意信号处理程序(例如SIGALRM)引发异常。
我的问题是哪些信号正在捕获指令,哪些不是?
#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是最可能的同步信号(即,由于尝试执行无效操作的指令而由硬件生成)。