33ERS_DECLARE_ISSUE(
ers, UnhandledException,
"Unhandled '" << name <<
"' exception has been thrown", ((
const char*)name))
44 struct sigaction old_action_;
46 static void action(
int, siginfo_t*,
void*);
49 SignalHandler(
int signal,
const char* sig_name)
55 sa.sa_sigaction = action;
56 sigemptyset(&sa.sa_mask);
57 sa.sa_flags = SA_SIGINFO;
59 ::sigaction(signal_, &sa, &old_action_);
62 ~SignalHandler() { ::sigaction(signal_, &old_action_, 0); }
66 friend class SignalHandler;
73 static void terminate_handler();
75 static std::map<int, SignalHandler*> handlers;
79ErrorHandler::SignalHandler::action(
int signal, siginfo_t*,
void* ucontext)
81 static bool recursive_invocation =
false;
82 if (recursive_invocation) {
83 std::cerr <<
"Got signal " << signal <<
" " << handlers[signal]->name_ <<
", aborting the program ..." << std::endl;
86 recursive_invocation =
true;
88 ers::SignalCatched ex(
ERS_HERE_DEBUG, signal, handlers[signal]->name_.c_str());
90 if (ex.context().stack_size() > 1) {
92 ucontext_t* uc = (ucontext_t*)ucontext;
93 const_cast<void**
>(ex.context().stack_symbols())[1] = (
void*)uc->uc_mcontext.gregs[REG_RIP];
96 ErrorHandler::abort(ex);
99ErrorHandler::ErrorHandler()
101 if (!::getenv(
"DUNEDAQ_ERS_NO_SIGNAL_HANDLERS")) {
102 handlers[SIGSEGV] =
new SignalHandler(SIGSEGV,
"Segmentation fault (invalid memory reference)");
103 handlers[SIGBUS] =
new SignalHandler(SIGBUS,
"Bus error (bad memory access)");
104 handlers[SIGILL] =
new SignalHandler(SIGILL,
"Illegal Instruction");
105 handlers[SIGFPE] =
new SignalHandler(SIGFPE,
"Floating point exception");
106 std::set_terminate(terminate_handler);
107#if __cplusplus < 201703L
108 std::set_unexpected(terminate_handler);
113ErrorHandler::~ErrorHandler()
115 std::map<int, SignalHandler*>::iterator it;
116 for (it = handlers.begin(); it != handlers.end(); ++it) {
122ErrorHandler::terminate_handler()
124 static bool recursive_invocation =
false;
125 if (recursive_invocation) {
126 std::cerr <<
"Unhandled exception has been thrown, aborting the program ..." << std::endl;
129 recursive_invocation =
true;
135 }
catch (std::exception& ex) {
136 ErrorHandler::abort(UnhandledException(
ERS_HERE_DEBUG,
"std::exception", ex));
138 ErrorHandler::abort(UnhandledException(
ERS_HERE_DEBUG,
"unknown"));
145 StandardStreamOutput::println(std::cerr, issue, 13);
150std::map<int, ers::ErrorHandler::SignalHandler*> ers::ErrorHandler::handlers;
153ers::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)