#include <SignalManager.hpp> #include <BacktraceManager.hpp> #include <ConsoleManager.hpp> #include <csignal> #include <rang.hpp> std::string SignalManager::s_pause_on_error = "auto"; void SignalManager::setPauseForDebug(const std::string& pause_on_error) { s_pause_on_error = pause_on_error; } std::string SignalManager::signalName(const int& signal) { switch (signal) { case SIGILL: return "SIGILL"; case SIGFPE: return "SIGFPE"; case SIGABRT: return "SIGABRT"; case SIGINT: return "SIGINT"; case SIGSEGV: return "SIGSEGV"; case SIGTERM: return "SIGTERM"; } return "SIGNAL undefined!"; } void SignalManager::pauseForDebug(const int& signal) { std::cout << "\n======================================\n"; std::cout << rang::style::reset << rang::fg::reset << rang::style::bold; std::cout << "to attach gdb to this process run\n"; std::cout << "\tgdb -pid " << rang::fg::red << getpid() << rang::fg::reset << '\n'; std::cout << "else press Control-C to exit\n"; std::cout << rang::style::reset; std::cout << "======================================\n"; std::cout << std::flush; ::sigset_t sig; ::sigaddset(&sig,SIGSTOP); ::sigsuspend(&sig); std::exit(signal); } void SignalManager::handler(int signal) { std::signal(SIGFPE, SIG_DFL); std::signal(SIGSEGV, SIG_IGN); std::signal(SIGTERM, SIG_DFL); std::signal(SIGINT, SIG_DFL); std::signal(SIGABRT, SIG_DFL); std::cerr << "\n *** " << rang::style::reset << rang::fg::reset << rang::style::bold; std::cerr << "Signal " << rang::fgB::yellow << signalName(signal) << rang::fg::reset << " caught" << rang::style::reset << " ***\n"; BacktraceManager bm; std::cerr << bm << '\n'; if ((ConsoleManager::isTerminal(std::cout) and (s_pause_on_error == "auto")) or (s_pause_on_error == "yes")) { SignalManager::pauseForDebug(signal); } else { std::exit(signal); } } void SignalManager::init(const bool& enable) { if (enable) { std::signal(SIGFPE, SignalManager::handler); std::signal(SIGSEGV, SignalManager::handler); std::signal(SIGTERM, SignalManager::handler); std::signal(SIGINT, SignalManager::handler); std::signal(SIGABRT, SignalManager::handler); std::signal(SIGPIPE, SignalManager::handler); std::cout << "Signal management: " << rang::style::bold << rang::fgB::green << "enabled" << rang::fg::reset << rang::style::reset << '\n'; } else { std::cout << "Signal management: " << rang::style::bold << rang::fgB::red << "disabled" << rang::fg::reset << rang::style::reset << '\n'; } }