Quinoa regression test code coverage report
Current view: top level - Base - ProcessException.cpp (source / functions) Hit Total Coverage
Commit: Quinoa_v0.3-957-gb4f0efae0 Lines: 10 37 27.0 %
Date: 2021-11-09 13:40:20 Functions: 1 4 25.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 65 0.0 %

           Branch data     Line data    Source code
       1                 :            : // *****************************************************************************
       2                 :            : /*!
       3                 :            :   \file      src/Base/ProcessException.cpp
       4                 :            :   \copyright 2012-2015 J. Bakosi,
       5                 :            :              2016-2018 Los Alamos National Security, LLC.,
       6                 :            :              2019-2021 Triad National Security, LLC.
       7                 :            :              All rights reserved. See the LICENSE file for details.
       8                 :            :   \brief     Process an exception
       9                 :            :   \details   This file contains the implementation of processing an exception.
      10                 :            :     Logically, it would make sense to put this into Exception.C, however,
      11                 :            :     Exception.h is included by all who want to be able throw an exception (a
      12                 :            :     potentially large number of files) and that would pull in the charm++.h as
      13                 :            :     well as the mpi.h headers, which triggers a slew of compiler warnings. On
      14                 :            :     the other hand, processing an exception is only done by the executables'
      15                 :            :     main chares objects and a few select explicit main() routines that use MPI,
      16                 :            :     which is a lot less than those which throw, so processing an exception is
      17                 :            :     separated here.
      18                 :            : */
      19                 :            : // *****************************************************************************
      20                 :            : 
      21                 :            : #include <cstdio>
      22                 :            : #include <csignal>
      23                 :            : #include <exception>
      24                 :            : #include <cfenv>
      25                 :            : 
      26                 :            : #include "NoWarning/charm.hpp"
      27                 :            : #include "NoWarning/mpi.hpp"
      28                 :            : 
      29                 :            : #include "Exception.hpp"
      30                 :            : #include "ProcessException.hpp"
      31                 :            : #include "QuinoaBuildConfig.hpp"
      32                 :            : 
      33                 :            : namespace tk {
      34                 :            : 
      35                 :            : void
      36                 :          0 : signalHandler( int signum )
      37                 :            : // *****************************************************************************
      38                 :            : // Signal handler for multiple signals, SIGABRT, SIGSEGV, etc.
      39                 :            : //! \param[in] signum Signal number
      40                 :            : //! \see https://oroboro.com/stack-trace-on-crash
      41                 :            : //! \details Signals caught:
      42                 :            : //!    SIGABRT is generated when the program calls the abort() function, such as
      43                 :            : //!            when an assert() triggers
      44                 :            : //!    SIGSEGV is generated when the program makes an illegal memory access, such
      45                 :            : //!            as reading unaligned memory, dereferencing a null pointer, reading
      46                 :            : //!            memory out of bounds etc.
      47                 :            : //!     SIGILL is generated when the program tries to execute a malformed
      48                 :            : //!            instruction. This happens when the execution pointer starts reading
      49                 :            : //!            non-program data, or when a pointer to a function is corrupted.
      50                 :            : //!     SIGFPE is generated when executing an illegal floating point instruction,
      51                 :            : //!            most commonly division by zero or floating point overflow.
      52                 :            : // *****************************************************************************
      53                 :            : {
      54                 :            :   // associate each signal with a signal name string.
      55                 :            :   const char* name = nullptr;
      56 [ -  - ][ -  - ]:          0 :   switch( signum ) {
            [ -  - ][ - ]
      57                 :            :     case SIGABRT: name = "SIGABRT";  break;
      58                 :          0 :     case SIGFPE:  name = "SIGFPE";   break;
      59                 :          0 :     case SIGILL:  name = "SIGILL";   break;
      60                 :          0 :     case SIGINT:  name = "SIGINT";   break;
      61                 :          0 :     case SIGSEGV: name = "SIGSEGV";  break;
      62                 :          0 :     case SIGTERM: name = "SIGTERM";  break;
      63                 :            :   }
      64                 :            : 
      65                 :            :   // Echo what signal is caught
      66                 :            :   if ( name )
      67                 :          0 :     fprintf( stderr, "Caught signal %d (%s)\n", signum, name );
      68                 :            :   else
      69                 :          0 :     fprintf( stderr, "Caught signal %d\n", signum );
      70                 :            : 
      71                 :            :   // Get and display backtrace
      72 [ -  - ][ -  - ]:          0 :   tk::Exception("Signal caught").handleException();
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
                 [ -  - ]
      73                 :            : 
      74                 :            :   // Tell the runtime system to exit with a nonzero exit code
      75                 :          0 :   CkExit(1);
      76                 :          0 : }
      77                 :            : 
      78                 :            : int
      79                 :        329 : setSignalHandlers()
      80                 :            : // *****************************************************************************
      81                 :            : // Set signal handlers for multiple signals, SIGABRT, SIGSEGV, etc
      82                 :            : //! \return Ignore, used for calling in a constructor's initializer list
      83                 :            : // *****************************************************************************
      84                 :            : {
      85                 :            :   // override Charm++'s terminate handler
      86                 :        329 :   std::set_terminate( [](){
      87 [ -  - ][ -  - ]:          0 :     tk::Exception("Terminate was called").handleException();
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
                 [ -  - ]
      88                 :            :     // Tell the runtime system to exit with a nonzero exit code
      89                 :          0 :     CkExit(1);
      90                 :          0 :   } );
      91                 :            : 
      92                 :        329 :   signal( SIGABRT, tk::signalHandler );
      93                 :        329 :   signal( SIGFPE,  tk::signalHandler );
      94                 :        329 :   signal( SIGILL,  tk::signalHandler );
      95                 :        329 :   signal( SIGINT,  tk::signalHandler );
      96                 :        329 :   signal( SIGSEGV, tk::signalHandler );
      97                 :        329 :   signal( SIGTERM, tk::signalHandler );
      98                 :            : 
      99                 :            :   #if !defined(__APPLE__) && !defined(HOST_OS_ALPINE)
     100                 :        329 :   feenableexcept( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
     101                 :            :   #endif
     102                 :            : 
     103                 :        329 :   return 0;
     104                 :            : }
     105                 :            : 
     106                 :            : void
     107                 :          0 : processExceptionCharm()
     108                 :            : // *****************************************************************************
     109                 :            : //  Process an exception from the Charm++ runtime system
     110                 :            : //! \details See Josuttis, The C++ Standard Library - A Tutorial and Reference,
     111                 :            : //!    2nd Edition, 2012.
     112                 :            : // *****************************************************************************
     113                 :            : {
     114                 :            :   try {
     115                 :          0 :     throw;      // rethrow exception to deal with it here
     116                 :            :   }
     117                 :            :   // Catch tk::Exception
     118                 :          0 :   catch ( tk::Exception& qe ) {
     119         [ -  - ]:          0 :     if (!CkMyPe()) qe.handleException();
     120                 :            :   }
     121                 :            :   // Catch std::exception and transform it into tk::Exception without
     122                 :            :   // file:line:func information
     123                 :          0 :   catch ( std::exception& se ) {
     124 [ -  - ][ -  - ]:          0 :     tk::Exception qe( se.what() );
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     125         [ -  - ]:          0 :     if (!CkMyPe()) qe.handleException();
     126                 :            :   }
     127                 :            :   // Catch uncaught exception
     128                 :          0 :   catch (...) {
     129 [ -  - ][ -  - ]:          0 :     tk::Exception qe( "Non-standard exception" );
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     130         [ -  - ]:          0 :     if (!CkMyPe()) qe.handleException();
     131                 :            :   }
     132                 :            : 
     133                 :            :   // Tell the runtime system to exit with a nonzero exit code
     134                 :          0 :   CkExit(1);
     135                 :          0 : }
     136                 :            : 
     137                 :            : } // tk::

Generated by: LCOV version 1.14