diff --git a/configure.ac b/configure.ac index 1a623a8..a434d7a 100644 --- a/configure.ac +++ b/configure.ac @@ -315,6 +315,18 @@ AC_ARG_ENABLE([hpc], AS_IF([test "x$enable_hpc" = "xyes"], [AC_DEFINE([HAVE_HPC], [1], [Activate HPC routines])]) + +AC_ARG_ENABLE([fpe], + [AS_HELP_STRING([--enable-fpe], + [Enable floating-point exceptions])], + [enable_fpe=$enableval], + [enable_fpe=no]) + +AS_IF([test "x$enable_fpe" = "xyes"], + [AC_DEFINE([HAVE_FPE], [1], [Activate floating-point exceptions])]) + + + AC_ARG_ENABLE([doc], [AS_HELP_STRING([--disable-doc], [Disable documentation])], diff --git a/org/qmckl_numprec.org b/org/qmckl_numprec.org index 3174464..c3522be 100644 --- a/org/qmckl_numprec.org +++ b/org/qmckl_numprec.org @@ -40,6 +40,42 @@ int main() { #include #include +#ifdef HAVE_FPE +#define _GNU_SOURCE +#include +#include +#include +#include + + +#define MAX_BACKTRACE_SIZE 100 + +void floatingPointExceptionHandler(int signal) { + void* backtraceArray[MAX_BACKTRACE_SIZE]; + int backtraceSize = backtrace(backtraceArray, MAX_BACKTRACE_SIZE); + char** backtraceSymbols = backtrace_symbols(backtraceArray, backtraceSize); + + // Print the backtrace + for (int i = 0; i < backtraceSize; ++i) { + printf("[%d] %s\n", i, backtraceSymbols[i]); + } + + // Clean up the memory used by backtrace_symbols + free(backtraceSymbols); + + exit(EXIT_FAILURE); +} + +static void __attribute__ ((constructor)) +trapfpe () +{ + /* Enable some exceptions. At startup all exceptions are masked. */ + + feenableexcept (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW); + signal(SIGFPE, floatingPointExceptionHandler); +} +#endif + #include "qmckl.h" #include "qmckl_context_private_type.h" #+end_src