diff --git a/utils/SignalManager.cpp b/utils/SignalManager.cpp index 4ef3fefc9dc689022641665bf2da8cd8c80e067e..ab84325bbf0ee9d0f085fcbada158227d5bf3076 100644 --- a/utils/SignalManager.cpp +++ b/utils/SignalManager.cpp @@ -1,5 +1,7 @@ #include <SignalManager.hpp> #include <ConsoleManager.hpp> +#include <Kokkos_Core.hpp> + #include <csignal> #include <rang.hpp> #include <iomanip> @@ -9,40 +11,58 @@ #include <regex> #include <vector> -void print_bt() { - const int size = 20; +std::vector<std::string> getBacktrace() +{ + const int size = 100; void *buffer[size]; - int ret = backtrace( buffer, size ); + int ret = ::backtrace(buffer, size); char **ptr = backtrace_symbols( buffer, ret ); - std::vector<std::string> lines; - for (int i=0; i<ret; ++i) { - lines.push_back(ptr[i]); + std::vector<std::string> backtrace; + for (int i=2; i<ret; ++i) { + backtrace.push_back(ptr[i]); } - free( ptr ); + free(ptr); + + return backtrace; +} + +void print_bt() { + + const std::vector<std::string> lines = getBacktrace(); - // abi::__cxa_demangle( "_Z16displayBacktracev", NULL, NULL, &status ); - std::regex mangled_function(R"(\(.*\+)"); - for (const auto& line : lines) { - std::cerr << "demangling " << line << '\n'; + const std::regex mangled_function(R"%(\(.*\+)%"); + const int width=std::log10(lines.size())+1; + + for (size_t i_line=0; i_line<lines.size(); ++i_line) { + const auto& line = lines[i_line]; + std::cerr << rang::fg::green << "[" << std::setw(width) << i_line+1 << '/' << lines.size() << "] " << rang::fg::reset; std::smatch matchex; int status = -1; if (std::regex_search(line, matchex, mangled_function)) { std::string prefix = matchex.prefix().str(); std::string function = line.substr(matchex.position()+1,matchex.length()-2); std::string suffix = matchex.suffix().str(); - std::cerr << "Found " << function.c_str() << '\n'; - std::string demangled = abi::__cxa_demangle(function.c_str(), NULL, NULL, &status); - std::cerr << "status=" << status << '\n'; - std::cerr << demangled << '\n'<< '\n'; + + std::cerr << prefix << '('; + if (function.size() > 0) { + char* demangled = abi::__cxa_demangle(function.c_str(), NULL, NULL, &status); + if (status==0) { + std::cerr << rang::fgB::yellow << demangled << rang::fg::reset; + free(demangled); + } else { + std::cerr << rang::fgB::yellow << function << rang::fg::reset; + } + } + std::cerr<< '+' << suffix << '\n'; + } else { + std::cerr << line << '\n'; } } } - - #warning must create a specific class for pausing and use enum class #include <string> std::string SignalManager::s_pause_on_error = "auto"; @@ -54,12 +74,12 @@ void SignalManager::setPauseForDebug(const std::string& pause_on_error) std::string SignalManager::signalName(int s) { switch (s) { - case SIGTERM: return "SIGTERM"; - case SIGSEGV: return "SIGSEGV"; - case SIGINT: return "SIGINT"; case SIGILL: return "SIGILL"; - case SIGABRT: return "SIGABRT"; case SIGFPE: return "SIGFPE"; + case SIGABRT: return "SIGABRT"; + case SIGINT: return "SIGINT"; + case SIGSEGV: return "SIGSEGV"; + case SIGTERM: return "SIGTERM"; } return "SIGNAL undefined!"; } @@ -67,35 +87,42 @@ std::string SignalManager::signalName(int s) void SignalManager::pauseForDebug() { - std::cerr << "\n======================================\n"; - std::cerr << rang::style::reset + std::cout << "\n======================================" << std::endl; + std::cout << rang::style::reset << rang::fg::reset << rang::style::bold; - std::cerr << "to attach gdb to this process run\n"; - std::cerr << "\tgdb -pid " + std::cout << "to attach gdb to this process run" << std::endl; + std::cout << "\tgdb -pid " << rang::fg::red << getpid() << rang::fg::reset << '\n'; - std::cerr << "else press Control-C to exit\n"; - std::cerr << rang::style::reset; - std::cerr << "======================================\n"; + std::cout << "else press Control-C to exit" << std::endl; + std::cout << rang::style::reset; + std::cout << "======================================" << std::endl; + + std::cout << std::flush; ::sigset_t sig; ::sigaddset(&sig,SIGSTOP); ::sigsuspend(&sig); -} -//#include <libunwind.h> + std::exit(1); +} void SignalManager::handler(int s) { + 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 *** " + std::cout << "\n *** " << rang::style::reset << rang::fg::reset << rang::style::bold; - std::cerr << "Signal " + std::cout << "Signal " << rang::fgB::yellow << signalName(s) << rang::fg::reset @@ -103,21 +130,14 @@ void SignalManager::handler(int s) << rang::style::reset << " ***\n"; - std::signal(SIGFPE, SIG_DFL); - std::signal(SIGSEGV, SIG_DFL); - std::signal(SIGTERM, SIG_DFL); - std::signal(SIGINT, SIG_DFL); - std::signal(SIGABRT, SIG_DFL); - print_bt(); - SignalManager::pauseForDebug(); if ((ConsoleManager::isTerminal(std::cout) and (s_pause_on_error == "auto")) or (s_pause_on_error == "yes")) { SignalManager::pauseForDebug(); } else { - // std::exit(0); + std::exit(1); } } @@ -130,6 +150,8 @@ void SignalManager::init(const bool& enable) 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