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++)
{