| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #include "Prerequisites/BsPrerequisitesUtil.h"
- #include "Debug/BsDebug.h"
- #include "FileSystem/BsFileSystem.h"
- #include <cxxabi.h>
- #include <execinfo.h>
- #include <ctime>
- #include <sstream>
- #include <csignal>
- namespace bs
- {
- CrashHandler::CrashHandler() {}
- CrashHandler::~CrashHandler() {}
- String CrashHandler::getCrashTimestamp()
- {
- std::time_t t = time(0);
- struct tm *now = localtime(&t);
- String timeStamp = "{0}{1}{2}_{3}{4}";
- String strYear = toString(now->tm_year, 4, '0');
- String strMonth = toString(now->tm_mon, 2, '0');
- String strDay = toString(now->tm_mday, 2, '0');
- String strHour = toString(now->tm_hour, 2, '0');
- String strMinute = toString(now->tm_min, 2, '0');
- return StringUtil::format(timeStamp, strYear, strMonth, strDay, strHour, strMinute);
- }
- String CrashHandler::getStackTrace()
- {
- StringStream stackTrace;
- void *trace[BS_MAX_STACKTRACE_DEPTH];
- int trace_size = backtrace(trace, BS_MAX_STACKTRACE_DEPTH);
- char **messages = backtrace_symbols(trace, trace_size);
- // Most lines returned by backtrace_symbols() look like this:
- //
- // <path/to/binary>(mangled_symbol+offset) [address]
- //
- // For those lines, we demangle the symbol with abi::__cxa_demangle(),
- // others are good as is.
- for (int i = 0; i < trace_size && messages != NULL; ++i)
- {
- // Try to find the characters surrounding the mangled name: '(' and '+'
- char *mangled_name = NULL, *offset_begin = NULL, *offset_end = NULL;
- for (char *p = messages[i]; *p; ++p)
- {
- if (*p == '(')
- mangled_name = p;
- else if (*p == '+')
- offset_begin = p;
- else if (*p == ')') {
- offset_end = p;
- break;
- }
- }
- bool lineContainsMangledSymbol = mangled_name != NULL
- && offset_begin != NULL
- && offset_end != NULL
- && mangled_name < offset_begin;
- stackTrace << toString(i) << ") ";
- if (lineContainsMangledSymbol)
- {
- *mangled_name++ = '\0';
- *offset_begin++ = '\0';
- *offset_end++ = '\0';
- int status;
- char *real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status);
- char *output_name = status == 0 /* Demangling successful */? real_name : mangled_name;
- stackTrace << String(messages[i])
- << ": " << output_name
- << "+" << offset_begin << offset_end;
- free(real_name);
- }
- else
- stackTrace << String(messages[i]);
- if (i < trace_size - 1)
- stackTrace << "\n";
- }
- free(messages);
- return stackTrace.str();
- }
- void CrashHandler::reportCrash(const String& type,
- const String& description,
- const String& function,
- const String& file,
- UINT32 line) const
- {
- logErrorAndStackTrace(type, description, function, file, line);
- saveCrashLog();
- // Allow the debugger a chance to attach
- std::raise(SIGINT);
- }
- }
|