From 262fc7c8707503596405642c04c591139c7f3367 Mon Sep 17 00:00:00 2001 From: Leon Henrik Plickat Date: Fri, 19 Nov 2021 00:43:32 +0100 Subject: [PATCH] Print message on error signal --- wlopm.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/wlopm.c b/wlopm.c index fa2ff92..0301343 100644 --- a/wlopm.c +++ b/wlopm.c @@ -17,15 +17,20 @@ * along with this program. If not, see . */ +#include +#include +#include #include #include #include #include -#include -#include - +#include #include +#ifndef BSD +#include +#endif + #include "xdg-output-unstable-v1.h" #include "wlr-output-power-management-unstable-v1.h" @@ -405,8 +410,59 @@ static bool create_operation (const char *name, enum Power_mode power_mode) return true; } +/** + * Intercept error signals (like SIGSEGV and SIGFPE) so that we can try to + * print a fancy error message and a backtracke before letting the system kill us. + */ +static void handle_error (int signum) +{ + const char *msg = + "\n" + "┌──────────────────────────────────────────┐\n" + "│ │\n" + "│ wlopm has crashed. │\n" + "│ │\n" + "│ This is likely a bug, so please │\n" + "│ report this to the mailing list. │\n" + "│ │\n" + "│ ~leon_plickat/public-inbox@lists.sr.ht │\n" + "│ │\n" + "└──────────────────────────────────────────┘\n" + "\n"; + fputs(msg, stderr); + +#ifndef BSD + fputs("Attempting to get backtrace:\n", stderr); + + /* In some rare cases, getting a backtrace can also cause a segfault. + * There is nothing we can or should do about that. All hope is lost at + * that point. + */ + void *buffer[255]; + const int calls = backtrace(buffer, sizeof(buffer) / sizeof(void *)); + backtrace_symbols_fd(buffer, calls, fileno(stderr)); + fputs("\n", stderr); +#endif + + /* Let the default handlers deal with the rest. */ + signal(signum, SIG_DFL); + kill(getpid(), signum); +} + +/** + * Set up signal handlers. + */ +static void init_signals (void) +{ + signal(SIGSEGV, handle_error); + signal(SIGFPE, handle_error); + +} + int main(int argc, char *argv[]) { + init_signals(); + wl_list_init(&operations); for (int i = 1; i < argc; i++) {