36 "Unhandled '" << name <<
"' exception has been thrown",
37 ((
const char *)name) )
41 "Got signal " << signum <<
" " << name,
43 ((
const char *)name) )
53 struct sigaction old_action_;
55 static void action(
int , siginfo_t *,
void * );
59 SignalHandler(
int signal,
const char * sig_name )
65 sa.sa_sigaction = action;
66 sigemptyset ( &sa.sa_mask );
67 sa.sa_flags = SA_SIGINFO;
69 ::sigaction( signal_, &sa, &old_action_ );
74 ::sigaction( signal_, &old_action_, 0 );
79 friend class SignalHandler;
87 static void terminate_handler();
89 static std::map<int,SignalHandler*> handlers;
92 void ErrorHandler::SignalHandler::action(
int signal, siginfo_t*,
void *ucontext) {
93 static bool recursive_invocation =
false;
94 if (recursive_invocation) {
95 std::cerr <<
"Got signal " << signal <<
" " << handlers[signal]->name_
96 <<
", aborting the program ..." << std::endl;
99 recursive_invocation =
true;
101 ers::SignalCatched ex(
ERS_HERE_DEBUG, signal, handlers[signal]->name_.c_str());
103 if (ex.context().stack_size() > 1) {
105 ucontext_t *uc = (ucontext_t*) ucontext;
106 const_cast<void**
>(ex.context().stack_symbols())[1] = (
void*) uc->uc_mcontext.gregs[REG_RIP];
109 ErrorHandler::abort(ex);
112 ErrorHandler::ErrorHandler()
114 if ( !::getenv(
"DUNEDAQ_ERS_NO_SIGNAL_HANDLERS" ) )
116 handlers[SIGSEGV] =
new SignalHandler( SIGSEGV,
"Segmentation fault (invalid memory reference)" );
117 handlers[SIGBUS] =
new SignalHandler( SIGBUS,
"Bus error (bad memory access)" );
118 handlers[SIGILL] =
new SignalHandler( SIGILL,
"Illegal Instruction" );
119 handlers[SIGFPE] =
new SignalHandler( SIGFPE,
"Floating point exception" );
120 std::set_terminate( terminate_handler );
121#if __cplusplus < 201703L
122 std::set_unexpected( terminate_handler );
127 ErrorHandler::~ErrorHandler()
129 std::map<int,SignalHandler*>::iterator it;
130 for( it = handlers.begin(); it != handlers.end(); ++it ) {
135 void ErrorHandler::terminate_handler()
137 static bool recursive_invocation =
false;
138 if (recursive_invocation) {
139 std::cerr <<
"Unhandled exception has been thrown, aborting the program ..." << std::endl;
142 recursive_invocation =
true;
150 catch( std::exception & ex ) {
151 ErrorHandler::abort( UnhandledException(
ERS_HERE_DEBUG,
"std::exception", ex ) );
154 ErrorHandler::abort( UnhandledException(
ERS_HERE_DEBUG,
"unknown" ) );
158 void ErrorHandler::abort(
const ers::Issue & issue )
165std::map<int,ers::ErrorHandler::SignalHandler*> ers::ErrorHandler::handlers;
169 ers::ErrorHandler __handler__;
Base class for any user define issue.
virtual const char * get_class_name() const =0
Get key for class (used for serialisation).
#define ERS_DECLARE_ISSUE( namespace_name, class_name, message_, attributes)
static std::ostream & println(std::ostream &out, const Issue &issue, int verbosity)