linux: add simple crash handler that dumps stacktrace (#1020)

Since the Linux version seems much more unstable than the Windows one,
having more information where the crash occured will help with figuring
out where the problems are.

This commit adds a simple crash handler that dumps out the stacktrace,
it's only supported on Linux.
This commit is contained in:
Dennis Brakhane
2025-01-16 08:42:40 +01:00
committed by GitHub
parent 73d7a0d2f8
commit 17bf75fd35
3 changed files with 78 additions and 2 deletions
+6
View File
@@ -26,6 +26,12 @@ else ()
)
set(LIB_DXCOMPILER "libdxcompiler.so")
# needed for proper names in crash stacktrace
set_target_properties(WickedEngineEditor
PROPERTIES
ENABLE_EXPORTS ON
)
endif ()
# Copy content to build folder:
+70
View File
@@ -6,6 +6,13 @@
#include "icon.c"
#ifdef __linux__
# include <execinfo.h>
# include <csignal>
# include <cstdio>
# include <unistd.h>
#endif
using namespace std;
Editor editor;
@@ -92,8 +99,71 @@ void set_window_icon(SDL_Window *window) {
SDL_FreeSurface(icon);
}
#ifdef __linux__
void crash_handler(int sig)
{
void* btbuf[100];
char outbuf[256];
size_t size = backtrace(btbuf, 100);
snprintf(
outbuf, sizeof(outbuf),
"Signal: %i (%s)\n"
"Version: %s\nStacktrace:\n",
sig,
sigdescr_np(sig),
wi::version::GetVersionString()
);
fprintf(
stderr,
"\e[31m" // red
"The editor just crashed, sorry about that! If you make a bug report, please include the following information:\n\n%s",
outbuf
);
backtrace_symbols_fd(btbuf, size, STDERR_FILENO); // backtrace_symbols does a malloc which could crash, backtrace_symbols_fd does not.
fprintf(stderr, "\e[m"); // back to normal
// finally, we also try to write the crash data to a file
// this might fail because we're in a weird state right now, but there's no harm done if it doesn't work
// Use C interface because some stuff in the c++ stdlib could be calling malloc
const char* filename = "wicked-editor-crash-log.txt";
FILE* logfile = fopen(filename, "w");
if (logfile != nullptr)
{
fputs(outbuf, logfile);
fflush(logfile);
backtrace_symbols_fd(btbuf, size, fileno(logfile));
fclose(logfile);
char cwdbuf[200];
fprintf(stderr, "\e[1mcrash log written to %s/%s\e[m\n", getcwd(cwdbuf, sizeof(cwdbuf)), filename);
}
exit(1);
}
#endif
int main(int argc, char *argv[])
{
#ifdef __linux__
// dummy backtrace() call to force libgcc to be loaded ahead of time.
// Otherwise it might lead to malloc calls in the crash_handler, which we want to avoid
void* dummy[1];
backtrace(dummy, 1);
for (int sig : std::array{SIGABRT, SIGBUS, SIGILL, SIGFPE, SIGSEGV})
{
signal(sig, crash_handler);
}
#endif
wi::arguments::Parse(argc, argv);
sdl2::sdlsystem_ptr_t system = sdl2::make_sdlsystem(SDL_INIT_EVERYTHING | SDL_INIT_EVENTS);
+2 -2
View File
@@ -8,8 +8,8 @@
#include <string>
#include <cassert>
#define wilog_level(str,level,...) {char text[1024] = {}; snprintf(text, sizeof(text), str, ## __VA_ARGS__); wi::backlog::post(text, level);}
#define wilog_messagebox(str,...) {char text[1024] = {}; snprintf(text, sizeof(text), str, ## __VA_ARGS__); wi::backlog::post(text, wi::backlog::LogLevel::Error); wi::helper::messageBox(text, "Error!");}
#define wilog_level(str,level,...) {char text[1024]; snprintf(text, sizeof(text), str, ## __VA_ARGS__); wi::backlog::post(text, level);}
#define wilog_messagebox(str,...) {char text[1024]; snprintf(text, sizeof(text), str, ## __VA_ARGS__); wi::backlog::post(text, wi::backlog::LogLevel::Error); wi::helper::messageBox(text, "Error!");}
#define wilog_warning(str,...) {wilog_level(str, wi::backlog::LogLevel::Warning, ## __VA_ARGS__);}
#define wilog_error(str,...) {wilog_level(str, wi::backlog::LogLevel::Error, ## __VA_ARGS__);}
#define wilog(str,...) {wilog_level(str, wi::backlog::LogLevel::Default, ## __VA_ARGS__);}