// Compile with: g++ test2.cpp -o test2 //#define TestMySignalHandler #ifndef TestMySignalHandler # include # include # include #endif #include #include #include #include // sigaction #include // memset #include void floating_point_exception_handler(int signal, siginfo_t *info, void * ucontext) { // throwing an exception here is undefined by the ANSI C++ Standard. std::cerr << "Floating point exception occurred -- aborting" << std::endl; std::abort(); // no other solution exists? } void install_handler(int signal, void (*handler)(int, siginfo_t *, void *)) { struct sigaction newhandler; memset(&newhandler,0,sizeof(newhandler)); newhandler.sa_sigaction=handler; newhandler.sa_flags=SA_SIGINFO; if (sigaction(signal,&newhandler,0)) throw std::runtime_error("Error installing signal handler"); } class myClass { public: myClass() { std::cout << "constructor" << std::endl; } ~myClass() { std::cout << "destructor" << std::endl; } }; void myTest() { myClass myC; int x = 0; // Not terminating in the signal handler will create an infinite loop // as the instruction pointer is set to the command *before* 1/x, see // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26208 ?!! (g++ 4.1, 4.2.1) std::cout << "1/x=" << 1/x << std::endl; #ifndef TestMySignalHandler BOOST_CHECK_SMALL(1.0*x, 1E-13); #endif } #ifndef TestMySignalHandler boost::unit_test::test_suite* init_unit_test_suite(int, char *[]) { install_handler(SIGFPE, floating_point_exception_handler); boost::unit_test::test_suite *test = BOOST_TEST_SUITE("Master test suite"); test->add(BOOST_TEST_CASE(&myTest)); return test; } #else int main() { try { install_handler(SIGFPE, floating_point_exception_handler); myTest(); } catch (std::exception &ex) { std::cerr << "Catched exception: " << ex.what() << std::endl; } return 0; } #endif