| @@ -22,7 +22,6 @@ | |||||
| #include <thread> | #include <thread> | ||||
| #include <unistd.h> // for getopt | #include <unistd.h> // for getopt | ||||
| #include <signal.h> // for signal | #include <signal.h> // for signal | ||||
| #if defined ARCH_WIN | #if defined ARCH_WIN | ||||
| #include <windows.h> // for CreateMutex | #include <windows.h> // for CreateMutex | ||||
| #endif | #endif | ||||
| @@ -40,7 +39,7 @@ static void fatalSignalHandler(int sig) { | |||||
| FATAL("Fatal signal %d. Stack trace:\n%s", sig, system::getStackTrace().c_str()); | FATAL("Fatal signal %d. Stack trace:\n%s", sig, system::getStackTrace().c_str()); | ||||
| // osdialog_message(OSDIALOG_ERROR, OSDIALOG_OK, "Rack has crashed. See log.txt for details."); | |||||
| osdialog_message(OSDIALOG_ERROR, OSDIALOG_OK, "Rack has crashed. See log.txt for details."); | |||||
| exit(1); | exit(1); | ||||
| } | } | ||||
| @@ -99,7 +98,7 @@ int main(int argc, char *argv[]) { | |||||
| // We can now install a signal handler and log the output | // We can now install a signal handler and log the output | ||||
| // Mac has its own decent crash handler | // Mac has its own decent crash handler | ||||
| #if 0 | |||||
| #if defined ARCH_LIN | |||||
| if (!settings::devMode) { | if (!settings::devMode) { | ||||
| signal(SIGABRT, fatalSignalHandler); | signal(SIGABRT, fatalSignalHandler); | ||||
| signal(SIGFPE, fatalSignalHandler); | signal(SIGFPE, fatalSignalHandler); | ||||
| @@ -2,8 +2,10 @@ | |||||
| #include <string.hpp> | #include <string.hpp> | ||||
| #include <thread> | #include <thread> | ||||
| #include <regex> | |||||
| #include <dirent.h> | #include <dirent.h> | ||||
| #include <sys/stat.h> | #include <sys/stat.h> | ||||
| #include <cxxabi.h> // for __cxxabiv1::__cxa_demangle | |||||
| #if defined ARCH_LIN || defined ARCH_MAC | #if defined ARCH_LIN || defined ARCH_MAC | ||||
| #include <pthread.h> | #include <pthread.h> | ||||
| @@ -166,10 +168,32 @@ std::string getStackTrace() { | |||||
| stackLen = backtrace(stack, stackLen); | stackLen = backtrace(stack, stackLen); | ||||
| char **strings = backtrace_symbols(stack, stackLen); | char **strings = backtrace_symbols(stack, stackLen); | ||||
| // Skip the first line because it's this function. | |||||
| for (int i = 1; i < stackLen; i++) { | for (int i = 1; i < stackLen; i++) { | ||||
| s += string::f("%d: %s\n", stackLen - i - 1, strings[i]); | |||||
| s += string::f("%d: ", stackLen - i - 1); | |||||
| // Parse line | |||||
| std::regex r(R"((.*)\((.*)\+(.*)\) (.*))"); | |||||
| std::smatch match; | |||||
| std::string line = strings[i]; | |||||
| if (std::regex_search(line, match, r)) { | |||||
| s += match[1].str(); | |||||
| s += "("; | |||||
| std::string symbol = match[2].str(); | |||||
| // Demangle symbol | |||||
| char *symbolD = __cxxabiv1::__cxa_demangle(symbol.c_str(), NULL, NULL, NULL); | |||||
| if (symbolD) { | |||||
| symbol = symbolD; | |||||
| free(symbolD); | |||||
| } | |||||
| s += symbol; | |||||
| s += "+"; | |||||
| s += match[3].str(); | |||||
| s += ")"; | |||||
| } | |||||
| s += "\n"; | |||||
| } | } | ||||
| free(strings); | free(strings); | ||||
| #elif defined ARCH_WIN | #elif defined ARCH_WIN | ||||
| HANDLE process = GetCurrentProcess(); | HANDLE process = GetCurrentProcess(); | ||||
| SymInitialize(process, NULL, true); | SymInitialize(process, NULL, true); | ||||