1
0
Fork 0
mirror of https://gitlab.com/niansa/libcatch.git synced 2025-03-06 20:53:37 +01:00
libcatch/libcatch.c
2022-09-16 13:45:46 +02:00

61 lines
1.4 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <execinfo.h>
#include <signal.h>
#include "libcatch.h"
static char *libcatch_lastexpr = NULL;
unsigned char libcatch_behavior;
bool libcatch_faulty;
static void sighandler(int signal, siginfo_t *si, void *arg) {
size_t size;
void *array[10];
size = backtrace(array, sizeof(array));
fputs("An unexpected exception occurred\n", stderr);
if (size) {
backtrace_symbols_fd(array, size, STDERR_FILENO);
}
if (signal == SIGUSR1) {
fprintf(stderr, "[expr]: %s\n", libcatch_lastexpr);
perror("[errn]");
}
if (signal != SIGUSR1) {
libcatch_faulty = true;
}
if ((signal == SIGUSR1 || libcatch_behavior > 2) && libcatch_behavior != 0) {
fputs("Trying to continue code flow...\n", stderr);
if (libcatch_behavior == 1 || libcatch_behavior == 3) {
libcatch_behavior = 0;
}
} else {
abort();
}
}
void libcatch_init() {
struct sigaction sa;
// Prepare vars
libcatch_lastexpr = NULL;
libcatch_behavior = 0;
libcatch_faulty = false;
// Prepare sigaction
memset(&sa, 0, sizeof(struct sigaction));
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = sighandler;
sa.sa_flags = SA_SIGINFO;
// Set sigsegv handler
sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGUSR1, &sa, NULL);
}
void throw(char *exprstr) {
libcatch_lastexpr = exprstr;
raise(SIGUSR1);
}