diff --git a/CMakeLists.txt b/CMakeLists.txt index 7371063..8c4ef5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,7 @@ file(GLOB src "src/*/*.cpp" "src/*/*/*.cpp" "src/*/*/*/*.cpp" + "src/*/*/*/*/*.cpp" ) if (WIN32) diff --git a/src/helper/exceptions/crashhandler.cpp b/src/helper/exceptions/crashhandler.cpp new file mode 100644 index 0000000..6ea4cda --- /dev/null +++ b/src/helper/exceptions/crashhandler.cpp @@ -0,0 +1,38 @@ +#include "crashhandler.hpp" +#include +#include + +#if defined(__linux__) +#include +#endif + +void CrashHandler::init() +{ + std::set_terminate(terminateCallback); +#if defined(__linux__) + signal(SIGSEGV, signalHandler); + signal(SIGABRT, signalHandler); + signal(SIGFPE, signalHandler); +#endif +} + +void CrashHandler::terminateCallback() +{ + Fancy::fancy.logTime().failure() << "An exception crashed the program" << std::endl; + + try + { + std::rethrow_exception(std::current_exception()); + } + catch (const std::exception &exception) + { + Fancy::fancy.logTime().failure() << "Exception: " >> exception.what() << std::endl; + Fancy::fancy.logTime().failure() << "Exception Type: " >> typeid(exception).name() << std::endl; + } + catch (...) + { + Fancy::fancy.logTime().failure() << "Exception: " >> "unknown" << std::endl; + } + + backtrace(); +} \ No newline at end of file diff --git a/src/helper/exceptions/crashhandler.hpp b/src/helper/exceptions/crashhandler.hpp new file mode 100644 index 0000000..afdfefb --- /dev/null +++ b/src/helper/exceptions/crashhandler.hpp @@ -0,0 +1,15 @@ +#pragma once + +class CrashHandler +{ + private: + static void terminateCallback(); + static void backtrace(); + +#if defined(__linux__) + static void signalHandler(int); +#endif + + public: + static void init(); +}; \ No newline at end of file diff --git a/src/helper/exceptions/linux/linux.cpp b/src/helper/exceptions/linux/linux.cpp new file mode 100644 index 0000000..f42a611 --- /dev/null +++ b/src/helper/exceptions/linux/linux.cpp @@ -0,0 +1,35 @@ +#if defined(__linux__) +#include "../crashhandler.hpp" +#include +#include +#include + +void CrashHandler::backtrace() +{ + Fancy::fancy.logTime().success() << "Backtrace available!" << std::endl; + + void *elements[20]; + auto size = ::backtrace(elements, 20); + auto *stack = backtrace_symbols(elements, size); + + for (int i = 0; size > i; i++) + { + Fancy::fancy.logTime() << stack[i] << std::endl; + } + + free(stack); +} + +void CrashHandler::signalHandler(int signal) +{ + if (signal == SIGFPE) + { + Fancy::fancy.logTime().warning() << "This crash is probably related to a bad pulseaudio config!" << std::endl; + } + + Fancy::fancy.logTime().failure() << "Received Signal: " << signal << std::endl; + + backtrace(); + exit(1); // NOLINT +} +#endif \ No newline at end of file diff --git a/src/helper/exceptions/windows/windows.cpp b/src/helper/exceptions/windows/windows.cpp new file mode 100644 index 0000000..ccba3dc --- /dev/null +++ b/src/helper/exceptions/windows/windows.cpp @@ -0,0 +1,9 @@ +#if defined(_WIN32) +#include "../crashhandler.hpp" +#include + +void CrashHandler::backtrace() +{ + Fancy::fancy.logTime().failure() << "Backtrace is not available on Windows" << std::endl; +} +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 3df059f..51c04f1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,5 @@ #include "core/global/globals.hpp" +#include "helper/exceptions/crashhandler.hpp" #include "ui/impl/webview/webview.hpp" #include #include @@ -9,11 +10,20 @@ int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int) int main() #endif { +#if defined(_WIN32) + DWORD lMode; + HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); + GetConsoleMode(hStdout, &lMode); + SetConsoleMode(hStdout, lMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN); +#endif + + CrashHandler::init(); + InstanceGuard::InstanceGuard guard("soundux-guard"); if (guard.IsAnotherInstanceRunning()) { Fancy::fancy.logTime().failure() << "Another Instance is already running!" << std::endl; - std::terminate(); + return 1; } #if defined(__linux__)