Matthias Volk
5 years ago
1 changed files with 0 additions and 175 deletions
@ -1,175 +0,0 @@ |
|||||
/* |
|
||||
* File: ErrorHandling.h |
|
||||
* Author: Gereon Kremer |
|
||||
* |
|
||||
* Created on March 15, 2013, 4:10 PM |
|
||||
*/ |
|
||||
|
|
||||
#ifndef ERRORHANDLING_H |
|
||||
#define ERRORHANDLING_H |
|
||||
|
|
||||
#include "storm/utility/OsDetection.h" |
|
||||
#include <signal.h> |
|
||||
|
|
||||
|
|
||||
/* |
|
||||
* Demangles the given string. This is needed for the correct display of backtraces. |
|
||||
* |
|
||||
* @param symbol The name of the symbol that is to be demangled. |
|
||||
*/ |
|
||||
std::string demangle(char const* symbol) { |
|
||||
// Attention: sscanf format strings rely on the size being 128. |
|
||||
char temp[128]; |
|
||||
|
|
||||
// Check for C++ symbol, on Non-MSVC Only |
|
||||
int scanResult = 0; |
|
||||
#ifdef WINDOWS |
|
||||
scanResult = sscanf_s(symbol, "%*[^(]%*[^_]%127[^)+]", temp, sizeof(temp)); |
|
||||
#else |
|
||||
int status; |
|
||||
scanResult = sscanf(symbol, "%*[^(]%*[^_]%127[^)+]", temp); |
|
||||
#endif |
|
||||
|
|
||||
if (scanResult == 1) { |
|
||||
#ifndef WINDOWS |
|
||||
char* demangled; |
|
||||
if (NULL != (demangled = abi::__cxa_demangle(temp, NULL, NULL, &status))) { |
|
||||
std::string result(demangled); |
|
||||
free(demangled); |
|
||||
return result; |
|
||||
} |
|
||||
#else |
|
||||
DWORD error; |
|
||||
HANDLE hProcess; |
|
||||
|
|
||||
SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS); |
|
||||
|
|
||||
hProcess = GetCurrentProcess(); |
|
||||
|
|
||||
if (!SymInitialize(hProcess, NULL, TRUE)) { |
|
||||
// SymInitialize failed |
|
||||
error = GetLastError(); |
|
||||
STORM_LOG_ERROR("SymInitialize returned error : " << error); |
|
||||
return FALSE; |
|
||||
} else { |
|
||||
char demangled[1024]; |
|
||||
if (UnDecorateSymbolName(temp, demangled, sizeof(demangled), UNDNAME_COMPLETE)) { |
|
||||
return std::string(demangled); |
|
||||
} else { |
|
||||
// UnDecorateSymbolName failed |
|
||||
DWORD error = GetLastError(); |
|
||||
STORM_LOG_ERROR("UnDecorateSymbolName returned error: " << error); |
|
||||
} |
|
||||
} |
|
||||
#endif |
|
||||
} |
|
||||
|
|
||||
// Check for C symbol. |
|
||||
scanResult = 0; |
|
||||
#ifdef WINDOWS |
|
||||
scanResult = sscanf_s(symbol, "%127s", temp, sizeof(temp)); |
|
||||
#else |
|
||||
scanResult = sscanf(symbol, "%127s", temp); |
|
||||
#endif |
|
||||
if (scanResult == 1) { |
|
||||
return temp; |
|
||||
} |
|
||||
|
|
||||
// Return plain symbol if none of the above cases matched. |
|
||||
return symbol; |
|
||||
} |
|
||||
|
|
||||
void showPerformanceStatistics(uint64_t wallclockMilliseconds); |
|
||||
|
|
||||
/* |
|
||||
* Handles the given signal. This will display the received signal and a backtrace. |
|
||||
* |
|
||||
* @param sig The code of the signal that needs to be handled. |
|
||||
*/ |
|
||||
void signalHandler(int sig) { |
|
||||
STORM_LOG_ERROR("The program received signal " << sig << ". The following backtrace shows the status upon reception of the signal."); |
|
||||
showPerformanceStatistics(0); |
|
||||
#ifndef WINDOWS |
|
||||
# define SIZE 128 |
|
||||
void *buffer[SIZE]; |
|
||||
char **strings; |
|
||||
int nptrs; |
|
||||
nptrs = backtrace(buffer, SIZE); |
|
||||
|
|
||||
// Try to retrieve the backtrace symbols. |
|
||||
strings = backtrace_symbols(buffer, nptrs); |
|
||||
if (strings == nullptr) { |
|
||||
std::cerr << "Obtaining the backtrace symbols failed." << std::endl; |
|
||||
exit(2); |
|
||||
} |
|
||||
|
|
||||
// Starting this for-loop at j=2 means that we skip the handler itself. Currently this is not |
|
||||
// done. |
|
||||
for (int j = 1; j < nptrs; j++) { |
|
||||
STORM_LOG_ERROR(nptrs-j << ": " << demangle(strings[j])); |
|
||||
} |
|
||||
free(strings); |
|
||||
#else |
|
||||
STORM_LOG_WARN("No Backtrace Support available on Platform Windows!"); |
|
||||
#endif |
|
||||
STORM_LOG_ERROR("Exiting."); |
|
||||
exit(2); |
|
||||
} |
|
||||
|
|
||||
/* |
|
||||
* Registers some signal handlers so that we can display a backtrace upon erroneuous termination. |
|
||||
*/ |
|
||||
void installSignalHandler() { |
|
||||
#ifndef WINDOWS |
|
||||
struct sigaction sa; |
|
||||
sa.sa_handler = signalHandler; |
|
||||
sigemptyset(&sa.sa_mask); |
|
||||
sa.sa_flags = SA_RESTART; |
|
||||
|
|
||||
if (sigaction(SIGSEGV, &sa, nullptr) == -1) { |
|
||||
std::cerr << "FATAL: Installing a signal handler failed." << std::endl; |
|
||||
} |
|
||||
if (sigaction(SIGABRT, &sa, nullptr) == -1) { |
|
||||
std::cerr << "FATAL: Installing a signal handler failed." << std::endl; |
|
||||
} |
|
||||
if (sigaction(SIGINT, &sa, nullptr) == -1) { |
|
||||
std::cerr << "FATAL: Installing a signal handler failed." << std::endl; |
|
||||
} |
|
||||
if (sigaction(SIGTERM, &sa, nullptr) == -1) { |
|
||||
std::cerr << "FATAL: Installing a signal handler failed." << std::endl; |
|
||||
} |
|
||||
if (sigaction(SIGALRM, &sa, nullptr) == -1) { |
|
||||
std::cerr << "FATAL: Installing a signal handler failed." << std::endl; |
|
||||
} |
|
||||
#else |
|
||||
signal(SIGSEGV, signalHandler); |
|
||||
signal(SIGABRT, signalHandler); |
|
||||
signal(SIGINT, signalHandler); |
|
||||
signal(SIGTERM, signalHandler); |
|
||||
#endif |
|
||||
} |
|
||||
|
|
||||
#ifdef WINDOWS |
|
||||
// This defines a placeholder-function to be called from SetTimer() which in turn calls the Signal Handler |
|
||||
VOID CALLBACK stormWindowsSetTimerCallBack( |
|
||||
HWND hwnd, // handle to window for timer messages |
|
||||
UINT message, // WM_TIMER message |
|
||||
UINT_PTR idEvent, |
|
||||
DWORD dwTime) // current system time |
|
||||
{ |
|
||||
// I believe that SIGALRM translates to 14, but it could be wrong! |
|
||||
signalHandler(14); |
|
||||
} |
|
||||
#endif |
|
||||
|
|
||||
void stormSetAlarm(uint_fast64_t timeoutSeconds) { |
|
||||
#ifndef WINDOWS |
|
||||
alarm(timeoutSeconds); |
|
||||
#else |
|
||||
// This needs more research (http://msdn.microsoft.com/en-us/library/windows/desktop/ms644906(v=vs.85).aspx) |
|
||||
UINT_PTR retVal = SetTimer(NULL, 0, static_cast<UINT>(timeoutSeconds * 1000), static_cast<TIMERPROC>(&stormWindowsSetTimerCallBack)); |
|
||||
#endif |
|
||||
} |
|
||||
|
|
||||
#endif /* ERRORHANDLING_H */ |
|
||||
|
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue