blob: 3507e0f5906eff0fd8e5231dfdd30b4cc02bc670 [file] [log] [blame]
swissChilib71e0272020-08-08 15:56:14 -07001#include "common.h"
2
3#include <signal.h>
4#include <stdlib.h>
5#include <stdio.h>
6
7catch_t g_catch[MAX_CATCH_LEN];
8unsigned g_catch_len;
9
swissChili4bccd442020-08-11 13:55:10 -070010void unwind()
swissChilib71e0272020-08-08 15:56:14 -070011{
swissChilib71e0272020-08-08 15:56:14 -070012 for (int i = g_catch_len - 1; i >= 0; i--)
13 {
14 g_catch[i].fn(g_catch[i].arg);
15 }
swissChili4bccd442020-08-11 13:55:10 -070016}
swissChilib71e0272020-08-08 15:56:14 -070017
swissChili4bccd442020-08-11 13:55:10 -070018void throw_(const char *msg, const char *file, unsigned int line)
19{
20 fprintf(stderr, "\033[31mException thrown:\033[33m %s:%d\033[0m %s\n", file, line, msg);
21 unwind();
swissChilib71e0272020-08-08 15:56:14 -070022 exit(1);
23}
24
25void catch_(handle_t hdl, intptr_t arg)
26{
27 if (g_catch_len > MAX_CATCH_LEN)
28 {
29 THROW("Catch overflow");
30 }
31
32 g_catch[g_catch_len++] = (catch_t){ .fn = hdl, .arg = arg };
33}
34
35void catch_signal(int sig)
36{
37 if (sig == SIGSEGV)
38 throw_("Segmentation fault", "unknown", 0);
39}
40
41__attribute__((constructor)) void init_catch()
42{
43 signal(SIGSEGV, catch_signal);
44}