25 "Unhandled '" << name <<
"' exception has been thrown",
26 ((
const char *)name) )
30 "Got signal " << signum <<
" " << name,
32 ((
const char *)name) )
42 struct sigaction old_action_;
44 static void action(
int , siginfo_t *,
void * );
48 SignalHandler(
int signal,
const char * sig_name )
54 sa.sa_sigaction = action;
55 sigemptyset ( &sa.sa_mask );
56 sa.sa_flags = SA_SIGINFO;
58 ::sigaction( signal_, &sa, &old_action_ );
63 ::sigaction( signal_, &old_action_, 0 );
68 friend class SignalHandler;
76 static void terminate_handler();
78 static std::map<int,SignalHandler*> handlers;
81 void ErrorHandler::SignalHandler::action(
int signal, siginfo_t*,
void *ucontext) {
82 static bool recursive_invocation =
false;
83 if (recursive_invocation) {
84 std::cerr <<
"Got signal " << signal <<
" " << handlers[signal]->name_
85 <<
", aborting the program ..." << std::endl;
88 recursive_invocation =
true;
90 ers::SignalCatched ex(
ERS_HERE_DEBUG, signal, handlers[signal]->name_.c_str());
92 if (ex.context().stack_size() > 1) {
94 ucontext_t *uc = (ucontext_t*) ucontext;
95 const_cast<void**
>(ex.context().stack_symbols())[1] = (
void*) uc->uc_mcontext.gregs[REG_RIP];
98 ErrorHandler::abort(ex);
101 ErrorHandler::ErrorHandler()
103 if ( !::getenv(
"DUNEDAQ_ERS_NO_SIGNAL_HANDLERS" ) )
105 handlers[SIGSEGV] =
new SignalHandler( SIGSEGV,
"Segmentation fault (invalid memory reference)" );
106 handlers[SIGBUS] =
new SignalHandler( SIGBUS,
"Bus error (bad memory access)" );
107 handlers[SIGILL] =
new SignalHandler( SIGILL,
"Illegal Instruction" );
108 handlers[SIGFPE] =
new SignalHandler( SIGFPE,
"Floating point exception" );
109 std::set_terminate( terminate_handler );
110#if __cplusplus < 201703L
111 std::set_unexpected( terminate_handler );
116 ErrorHandler::~ErrorHandler()
118 std::map<int,SignalHandler*>::iterator it;
119 for( it = handlers.begin(); it != handlers.end(); ++it ) {
124 void ErrorHandler::terminate_handler()
126 static bool recursive_invocation =
false;
127 if (recursive_invocation) {
128 std::cerr <<
"Unhandled exception has been thrown, aborting the program ..." << std::endl;
131 recursive_invocation =
true;
139 catch( std::exception & ex ) {
140 ErrorHandler::abort( UnhandledException(
ERS_HERE_DEBUG,
"std::exception", ex ) );
143 ErrorHandler::abort( UnhandledException(
ERS_HERE_DEBUG,
"unknown" ) );
147 void ErrorHandler::abort(
const ers::Issue & issue )
154std::map<int,ers::ErrorHandler::SignalHandler*> ers::ErrorHandler::handlers;
158 ers::ErrorHandler __handler__;
#define ERS_DECLARE_ISSUE(namespace_name, class_name, message, attributes)
Base class for any user define issue.
virtual const char * get_class_name() const =0
Get key for class (used for serialisation)
static std::ostream & println(std::ostream &out, const Issue &issue, int verbosity)