mirror of
https://gitlab.com/niansa/libcatch.git
synced 2025-03-06 20:53:37 +01:00
61 lines
1.4 KiB
C
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);
|
|
}
|