diff --git a/assert/assert.h b/assert/assert.h index a017d59a..771b2af1 100644 --- a/assert/assert.h +++ b/assert/assert.h @@ -11,11 +11,21 @@ #include "AssertFailed.h" #include #include +#include namespace cpputils { namespace _assert { inline std::string format(const char *expr, const char *message, const char *file, int line) { - return std::string()+"Assertion ["+expr+"] failed in "+file+":"+std::to_string(line)+": "+message; + // get void*'s for all entries on the stack + void *array[10]; + size_t size = backtrace(array, sizeof(array)); + char **backtrace_str = backtrace_symbols(array, sizeof(backtrace_str)); + std::string result = std::string()+"Assertion ["+expr+"] failed in "+file+":"+std::to_string(line)+": "+message+"\n\n"; + for (unsigned int i = 0; i < size; ++i) { + result += std::string(backtrace_str[i]) + "\n"; + } + free(backtrace_str); + return result; } inline void assert_fail_release [[noreturn]] (const char *expr, const char *message, const char *file, int line) { diff --git a/assert/backtrace.cpp b/assert/backtrace.cpp new file mode 100644 index 00000000..c5301f86 --- /dev/null +++ b/assert/backtrace.cpp @@ -0,0 +1,21 @@ +#include "backtrace.h" +#include +#include +#include +#include + +namespace cpputils { + + void sigsegv_handler(int) { + void *array[100]; + size_t size = backtrace(array, sizeof(array)); + + std::cerr << "Error: SIGSEGV" << std::endl; + backtrace_symbols_fd(array, size, STDERR_FILENO); + exit(1); + } + + void showBacktraceOnSigSegv() { + signal(SIGSEGV, sigsegv_handler); + } +} diff --git a/assert/backtrace.h b/assert/backtrace.h new file mode 100644 index 00000000..94811aa7 --- /dev/null +++ b/assert/backtrace.h @@ -0,0 +1,8 @@ +#ifndef MESSMER_CPPUTILS_ASSERT_BACKTRACE_H +#define MESSMER_CPPUTILS_ASSERT_BACKTRACE_H + +namespace cpputils { + void showBacktraceOnSigSegv(); +} + +#endif