// Ensure libunwind is compiled with exception handling code! // // To demonstrate the behaviour, compile with g++ -fnon-call-exceptions sigfpe.cpp -o sigfpe // and then run ./sigfpe vs. LD_PRELOAD=/usr/lib/libunwind.so.7 ./sigfpe // // If you just want to see the ip and the before-flag, compile with '-D SHOW_IP // #include #include #include #include #ifdef SHOW_IP extern "C" long _Unwind_GetIPInfo(void*, void*); int counter = 0; // Overwrite personality routine to demonstrate different behaviour // of _Unwind_GetIPInfo for gcc and libunwind extern "C" int __gxx_personality_v0(int, int, uint64_t, void*, void* context) { int before = 0; long ip = _Unwind_GetIPInfo(context, &before); printf("ip: 0x%lx, ip-before-ins: %d\n", ip, before); if (++counter == 2) { // Just exit after the second call // There should now be a difference between gcc and libunwind if (before == 0) { // Expected libunwind code path exit(1); } // Expected gcc code path exit(0); } return 8; // continue unwind... } #endif struct Test { ~Test() { } }; int i; void fpe() { Test test; i = 1 / 0; } void sighandler(int signo) { throw 0; } int main (int argc, char **argv) { try { signal(SIGFPE, &sighandler); fpe(); } catch (int) { printf("caught...\n"); } }