#include #include #include #include "data.h" /* Define this macro to install a signal handler that prints out * details about the exception. */ /* #define USE_SIGNAL_HANDLER */ #if defined(USE_SIGNAL_HANDLER) #include static void signalhandler(int signo, siginfo_t *info, void *ctx) { char const *type = ""; (void)ctx; switch (info->si_code) { case FPE_INTDIV: type = "integer division by zero"; break; case FPE_INTOVF: type = "integer overflow"; break; case FPE_FLTDIV: type = "floating-point divide by zero"; break; case FPE_FLTOVF: type = "floating-point overflow"; break; case FPE_FLTUND: type = "floating-point underflow"; break; case FPE_FLTRES: type = "floating-point inexact result"; break; case FPE_FLTINV: type = "floating-point invalid operation"; break; case FPE_FLTSUB: type = "subscript out of range"; break; } fprintf(stderr, "SIGFPE(%d): %s at %p\n", signo, type, info->si_addr); abort(); } #endif int main(void) { DATA data; double *chg4; BASE base = { &data }; int i; /* Explicitly enable the "floating point divide by zero" exception. */ #if !defined(NO_ENABLE_EXCEPT) feenableexcept(FE_DIVBYZERO); #endif /* Install a signal handler so that we can easily print information * about the floating point exception we receive. */ #if defined(USE_SIGNAL_HANDLER) { struct sigaction action; action.sa_sigaction = signalhandler; sigemptyset(&action.sa_mask); action.sa_flags = SA_SIGINFO; sigaction(SIGFPE, &action, NULL); } #endif /* Initialize arguments to function call. */ data.len1 = 100; data.len2 = 100; data.count = 0; if ( (data.d1 = malloc(data.len2 * sizeof(*data.d1))) == NULL || (data.d2 = malloc(data.len2 * sizeof(*data.d2))) == NULL || (data.c1 = malloc(data.len2 * sizeof(*data.c1))) == NULL || (data.c2 = malloc(data.len1 * sizeof(*data.c2))) == NULL || (chg4 = calloc(data.len2, sizeof(*chg4))) == NULL ) { fprintf(stderr, "Out of memory\n"); abort(); } for (i = 0; i < data.len2; ++i) { data.d1[i] = 0.0; data.d2[i] = 1.0; data.c1[i] = 'C'; } for (i = 0; i < data.len1; ++i) data.c2[i] = 'L'; /* Call the offending function. */ printf("%d\n", wrapper(&base, NULL, NULL, NULL, chg4, NULL)); /* Cleanup. */ free(chg4); free(data.c2); free(data.c1); free(data.d2); free(data.d1); return 0; }