LCOV - code coverage report
Current view: top level - ers/src - ErrorHandler.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 44.3 % 61 27
Test Date: 2026-07-12 15:23:06 Functions: 25.0 % 24 6

            Line data    Source code
       1              : /*
       2              :  * DUNE DAQ modification notice:
       3              :  * This file has been modified from the original ATLAS ers source for the DUNE DAQ project.
       4              :  * Fork baseline commit: 8267df82a4f6fe6bf02c4014923eba19eddc4614 (2020-04-14).
       5              :  * Renamed since fork: yes (from src/ErrorHandler.cxx to src/ErrorHandler.cpp).
       6              :  *
       7              :  * Original copyright:
       8              :  * Copyright (C) 2001-2020 CERN for the benefit of the ATLAS collaboration.
       9              :  * Licensed under the Apache License, Version 2.0.
      10              :  */
      11              : 
      12              : /*
      13              :  *  ErrorHandler.cxx
      14              :  *  ers
      15              :  *
      16              :  *  Created by Serguei Kolos on 02.08.05.
      17              :  *  Copyright 2005 CERN. All rights reserved.
      18              :  *
      19              :  */
      20              : #include <csignal>
      21              : #include <map>
      22              : #include <iomanip>
      23              : #include <iostream>
      24              : 
      25              : #ifdef ERS_NO_DEBUG
      26              : #undef ERS_NO_DEBUG
      27              : #endif
      28              : 
      29              : #include <ers/Issue.hpp>
      30              : #include <ers/ers.hpp>
      31              : #include <ers/StandardStreamOutput.hpp>
      32              : 
      33              : 
      34           76 : ERS_DECLARE_ISSUE(      ers, 
      35              :                         UnhandledException,
      36              :                         "Unhandled '" << name << "' exception has been thrown",
      37              :                         ((const char *)name) )
      38              : 
      39           76 : ERS_DECLARE_ISSUE(      ers, 
      40              :                         SignalCatched,
      41              :                         "Got signal " << signum << " " << name,
      42              :                         ((int)signum)
      43              :                         ((const char *)name) )
      44              : 
      45              : namespace ers
      46              : {    
      47              :     class ErrorHandler
      48              :     {        
      49              :         class SignalHandler
      50              :         {
      51              :             int                 signal_;
      52              :             std::string         name_;
      53              :             struct sigaction    old_action_;
      54              :                        
      55              :             static void action( int , siginfo_t *, void * );
      56              :             
      57              :           public:
      58              : 
      59          304 :             SignalHandler( int signal, const char * sig_name )
      60          304 :               : signal_( signal ),
      61          304 :                 name_( sig_name )
      62              :             {
      63          304 :                 struct sigaction sa;
      64              : 
      65          304 :                 sa.sa_sigaction = action;
      66          304 :                 sigemptyset ( &sa.sa_mask );
      67          304 :                 sa.sa_flags = SA_SIGINFO;
      68              : 
      69          304 :                 ::sigaction( signal_, &sa, &old_action_ );
      70          304 :             }
      71              : 
      72          304 :             ~SignalHandler( )
      73              :             {
      74          304 :                 ::sigaction( signal_, &old_action_, 0 );
      75          304 :             }
      76              :         };
      77              :                 
      78              :       public:
      79              :         friend class SignalHandler;
      80              :         
      81              :         ErrorHandler();
      82              :         ~ErrorHandler();
      83              :         
      84              :       private:  
      85              :         
      86              :         static void abort( const ers::Issue & issue );
      87              :         static void terminate_handler();
      88              :         
      89              :         static std::map<int,SignalHandler*> handlers;
      90              :     };
      91              :     
      92            0 :     void ErrorHandler::SignalHandler::action(int signal, siginfo_t*, void *ucontext) {
      93            0 :         static bool recursive_invocation = false;
      94            0 :         if (recursive_invocation) {
      95            0 :             std::cerr << "Got signal " << signal << " " << handlers[signal]->name_
      96            0 :                     << ", aborting the program ..." << std::endl;
      97            0 :             ::abort();
      98              :         }
      99            0 :         recursive_invocation = true;
     100              : 
     101            0 :         ers::SignalCatched ex( ERS_HERE_DEBUG, signal, handlers[signal]->name_.c_str());
     102              : #ifdef __x86_64__
     103            0 :         if (ex.context().stack_size() > 1) {
     104              :             /* overwrite sigaction with caller's address */
     105            0 :             ucontext_t *uc = (ucontext_t*) ucontext;
     106            0 :             const_cast<void**>(ex.context().stack_symbols())[1] = (void*) uc->uc_mcontext.gregs[REG_RIP];
     107              :         }
     108              : #endif
     109            0 :         ErrorHandler::abort(ex);
     110            0 :     }   
     111              :     
     112           76 :     ErrorHandler::ErrorHandler()
     113              :     {
     114           76 :         if ( !::getenv( "DUNEDAQ_ERS_NO_SIGNAL_HANDLERS" ) )
     115              :         {
     116           76 :             handlers[SIGSEGV] = new SignalHandler( SIGSEGV, "Segmentation fault (invalid memory reference)" );
     117           76 :             handlers[SIGBUS]  = new SignalHandler( SIGBUS, "Bus error (bad memory access)" );
     118           76 :             handlers[SIGILL]  = new SignalHandler( SIGILL, "Illegal Instruction" );
     119           76 :             handlers[SIGFPE]  = new SignalHandler( SIGFPE, "Floating point exception" );
     120           76 :             std::set_terminate( terminate_handler );
     121              : #if __cplusplus < 201703L
     122              :             std::set_unexpected( terminate_handler );
     123              : #endif
     124              :         }
     125           76 :     }
     126              :     
     127           76 :     ErrorHandler::~ErrorHandler()
     128              :     {
     129           76 :         std::map<int,SignalHandler*>::iterator it;
     130          380 :         for( it = handlers.begin(); it != handlers.end(); ++it ) {
     131          304 :             delete it->second;
     132              :         }
     133           76 :     }
     134              : 
     135            0 :     void ErrorHandler::terminate_handler()
     136              :     {
     137            0 :         static bool recursive_invocation = false;
     138            0 :         if (recursive_invocation) {
     139            0 :             std::cerr << "Unhandled exception has been thrown, aborting the program ..." << std::endl;
     140            0 :             ::abort();
     141              :         }
     142            0 :         recursive_invocation = true;
     143              :             
     144            0 :         try {
     145            0 :             throw;
     146              :         }
     147            0 :         catch( ers::Issue & ex ) {
     148            0 :             ErrorHandler::abort( UnhandledException( ERS_HERE_DEBUG, ex.get_class_name(), ex ) );
     149            0 :         }
     150            0 :         catch( std::exception & ex ) {
     151            0 :             ErrorHandler::abort( UnhandledException( ERS_HERE_DEBUG, "std::exception", ex ) );
     152            0 :         }
     153            0 :         catch(...) {
     154            0 :             ErrorHandler::abort( UnhandledException( ERS_HERE_DEBUG, "unknown" ) );
     155            0 :         }
     156            0 :     }
     157              :     
     158            0 :     void ErrorHandler::abort( const ers::Issue & issue )
     159              :     {
     160            0 :         StandardStreamOutput::println(std::cerr, issue, 13);
     161            0 :         ::abort();
     162              :     }
     163              : }
     164              : 
     165              : std::map<int,ers::ErrorHandler::SignalHandler*> ers::ErrorHandler::handlers;
     166              : 
     167              : namespace
     168              : {
     169              :     ers::ErrorHandler __handler__;
     170              : }
        

Generated by: LCOV version 2.0-1