[petsc-users] [petsc-maint #136411] PETSc Execution Error
Jed Brown
jedbrown at mcs.anl.gov
Sun Oct 21 09:01:30 CDT 2012
On Sun, Oct 21, 2012 at 7:17 AM, Kirk, Benjamin (JSC-EG311) <
benjamin.kirk-1 at nasa.gov> wrote:
> Aside from the debugger, you can enable floating point exceptions at
> runtime if there is interest.
>
Thanks for this. There is code for Linux (using feenableexcept) and a bunch
of esoteric architectures in petsc/src/sys/error/fp.c, activated when you
pass -fp_trap. It looks like the xmmintrin option there wasn't correct.
Also, I see that the specific cause of the exception is actually retained
in si_code, but with a different set of macros (FPE_FLTDIV) than
feenableexcept (FE_DIVBYZERO).
Satish and Barry, is there any rationale for still using signal(2), which
has been deprecated since 1988, instead of sigaction()?
>
> Below is the code we use on mac/linux in libMesh to honor --enable-fpe on
> the command line. Note this was adapted from code originally provided from
> INL by the Moose team, so thanks really goes to them! We prefer the
> feenableexcept() API on linux, but on the Mac you can get access to most of
> the exceptions through the MMX instruction set.
>
> Independent of the debugger it will still print the actual error and a
> stack trace, which is often good enough to know what happened.
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> // floating-point exceptions
> #ifdef LIBMESH_HAVE_FENV_H
> # include <fenv.h>
> #endif
> #ifdef LIBMESH_HAVE_XMMINTRIN_H
> # include <xmmintrin.h>
> #endif
>
>
>
> /**
> * Floating point exception handler -- courtesy of Cody Permann & MOOSE
> team
> */
> void libmesh_handleFPE(int /*signo*/, siginfo_t *info, void *
> /*context*/)
> {
> std::cout << std::endl;
> std::cout << "Floating point exception signaled (";
> switch (info->si_code)
> {
> case FPE_INTDIV: std::cerr << "integer divide by zero"; break;
> case FPE_INTOVF: std::cerr << "integer overflow"; break;
> case FPE_FLTDIV: std::cerr << "floating point divide by zero"; break;
> case FPE_FLTOVF: std::cerr << "floating point overflow"; break;
> case FPE_FLTUND: std::cerr << "floating point underflow"; break;
> case FPE_FLTRES: std::cerr << "floating point inexact result"; break;
> case FPE_FLTINV: std::cerr << "invalid floating point operation";
> break;
> case FPE_FLTSUB: std::cerr << "subscript out of range"; break;
> }
> std::cout << ")!" << std::endl;
>
> std::cout << std::endl;
> std::cout << "To track this down, compile debug version, start
> debugger, set breakpoint for 'libmesh_handleFPE' and run" << std::endl;
> std::cout << "In gdb do:" << std::endl;
> std::cout << " break libmesh_handleFPE" << std::endl;
> std::cout << " run ..." << std::endl;
> std::cout << " bt" << std::endl;
>
> libmesh_error();
> }
>
>
> /**
> * Toggle floating point exceptions -- courtesy of Cody Permann & MOOSE
> team
> */
> void enableFPE(bool on)
> {
> #if !defined(LIBMESH_HAVE_FEENABLEEXCEPT) &&
> defined(LIBMESH_HAVE_XMMINTRIN_H)
> static int flags = 0;
> #endif
>
> if (on)
> {
> struct sigaction new_action, old_action;
>
> #ifdef LIBMESH_HAVE_FEENABLEEXCEPT
> feenableexcept(FE_DIVBYZERO | FE_INVALID);
> #elif LIBMESH_HAVE_XMMINTRIN_H
> flags = _MM_GET_EXCEPTION_MASK(); // store the flags
> _MM_SET_EXCEPTION_MASK(flags & ~_MM_MASK_INVALID);
> #endif
>
>
> // Set up the structure to specify the new action.
> new_action.sa_sigaction = libmesh_handleFPE;
> sigemptyset (&new_action.sa_mask);
> new_action.sa_flags = SA_SIGINFO;
>
> sigaction (SIGFPE, NULL, &old_action);
> if (old_action.sa_handler != SIG_IGN)
> sigaction (SIGFPE, &new_action, NULL);
> }
> else
> {
> #ifdef LIBMESH_HAVE_FEDISABLEEXCEPT
> fedisableexcept(FE_DIVBYZERO | FE_INVALID);
> #elif LIBMESH_HAVE_XMMINTRIN_H
> _MM_SET_EXCEPTION_MASK(flags);
> #endif
> signal(SIGFPE, 0);
> }
> }
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20121021/3fc4463e/attachment.html>
More information about the petsc-users
mailing list