~leon_plickat/wat

d3c8dbea13b45dc834efb66f67149088dcd140ce — Leon Henrik Plickat 2 months ago 299fff0
Print message on error signals
1 files changed, 56 insertions(+), 0 deletions(-)

M wat.c
M wat.c => wat.c +56 -0
@@ 19,6 19,7 @@

#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>


@@ 26,6 27,10 @@
#include <sys/wait.h>
#include <unistd.h>

#ifndef BSD
#include<execinfo.h>
#endif

#include <wayland-client.h>

#include "xdg-activation-v1.h"


@@ 145,8 150,59 @@ static const struct wl_registry_listener registry_listener = {
	.global_remove = noop, /* We don't run long enough to care. */
};

/**
 * 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"
		"│            wat 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();

	for (int i = 1; i < argc; i++)
	{
		if ( strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0 )