SIGSEGVをキャッチし、なおかつそこから元の処理を継続する。
segv.cpp
#include <iostream> #include <signal.h> typedef void (*sighandler_t)(int); volatile sig_atomic_t a = 100; volatile sig_atomic_t p; void segvcatch(int sig) { signal(sig, SIG_IGN); //std::cout << "segv catched\t" << sig << std::endl; p = reinterpret_cast<sig_atomic_t>(&a); throw p; //std::cout << p << std::endl; signal(sig, segvcatch); } int main() { p = 0; if(SIG_ERR == signal(SIGSEGV, segvcatch)) { std::cout << "cannnot set segvcatch" << std::endl; } //std::cout << &a << std::endl; try { std::cout << *((int *)p) << std::endl; } catch (...) { std::cout << *((int *)p) << std::endl; } std::cout << "end of program" << std::endl; }
segv2.cpp
#include <iostream> #include <signal.h> typedef void (*sighandler_t)(int); volatile sig_atomic_t a = 100; int * p; void segvcatch(int sig) { signal(sig, SIG_IGN); std::cout << "segv catched\t" << sig << std::endl; throw p; //std::cout << p << std::endl; signal(sig, segvcatch); } int func() { std::cout << "func" << std::endl; std::cout << *p << std::endl; return 0; } int main() { p = 0; if(SIG_ERR == signal(SIGSEGV, segvcatch)) { std::cout << "cannnot set segvcatch" << std::endl; } //std::cout << &a << std::endl; try { func(); } catch (...) { std::cout << "catch logic" << std::endl; } std::cout << "end of program" << std::endl; }
$ g++ segv.cpp $ ./a.exe Segmentation fault (core dumped) $ g++ segv.cpp -fnon-call-exceptions 100 end of program $ g++ segv2.cpp func segv catched 11 catch logic end of program $ g++ segv2.cpp -fnon-call-exceptions func segv catched 11 catch logic end of program
gcc 2.95.4 では -fnon-call-exceptions が未実装
gcc 3.4.4 では動く(Linux,Cygwinで確認)