LlamaLib  v2.0.2
Cross-platform library for local LLMs
Loading...
Searching...
No Matches
error_handling.cpp
1#include "error_handling.h"
2
3ErrorState *ErrorStateRegistry::custom_error_state_ = nullptr;
4
5int &get_status_code()
6{
7 return ErrorStateRegistry::get_error_state().status_code;
8}
9
10std::string &get_status_message()
11{
12 return ErrorStateRegistry::get_error_state().status_message;
13}
14
15sigjmp_buf &get_sigjmp_buf_point()
16{
17 static sigjmp_buf sigjmp_buf_point;
18 return sigjmp_buf_point;
19}
20
21std::mutex &get_sigint_hook_mutex()
22{
23 static std::mutex sigint_hook_mutex;
24 return sigint_hook_mutex;
25}
26
27std::vector<Hook> &get_sigint_hooks()
28{
29 static std::vector<Hook> sigint_hooks;
30 return sigint_hooks;
31}
32
33void fail(std::string message, int code)
34{
36 error_state.status_code = code;
37 error_state.status_message = message;
38}
39
40void handle_exception(int code)
41{
42 try
43 {
44 throw;
45 }
46 catch (const std::exception &ex)
47 {
48 fail(ex.what(), code);
49 }
50 catch (...)
51 {
52 fail("Caught unknown exception", code);
53 }
54}
55
56sigjmp_buf &get_jump_point()
57{
58 sigjmp_buf &sigjmp_buf_point = get_sigjmp_buf_point();
59 fail("", 0);
60 return sigjmp_buf_point;
61}
62
63namespace {
64 thread_local sigjmp_buf* current_jump_point = nullptr;
65}
66
67sigjmp_buf* get_current_jump_point_ptr()
68{
69 return current_jump_point;
70}
71
72void set_current_jump_point(sigjmp_buf* jump_point)
73{
74 current_jump_point = jump_point;
75}
76
77static void handle_terminate()
78{
79 crash_signal_handler(1);
80}
81
82#ifdef _WIN32
83
84BOOL WINAPI console_ctrl_handler(DWORD ctrl_type)
85{
86 if (ctrl_type == CTRL_C_EVENT || ctrl_type == CTRL_CLOSE_EVENT)
87 {
88 sigint_signal_handler(SIGINT);
89 return TRUE;
90 }
91 return FALSE;
92}
93
94void set_error_handlers(bool crash_handlers, bool sigint_handlers)
95{
97
98 if (crash_handlers)
99 {
100 signal(SIGSEGV, crash_signal_handler);
101 signal(SIGFPE, crash_signal_handler);
102 std::set_terminate(handle_terminate);
103 }
104
105 if (sigint_handlers)
106 {
107 signal(SIGINT, sigint_signal_handler);
108 signal(SIGTERM, sigint_signal_handler);
109 SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
110 }
111}
112
113#else
114
115void handle_signal(int sig, siginfo_t *, void *)
116{
117 crash_signal_handler(sig);
118}
119
120void set_error_handlers(bool crash_handlers, bool sigint_handlers)
121{
123
124 if (crash_handlers)
125 {
126 struct sigaction sa{};
127 sigemptyset(&sa.sa_mask);
128 sa.sa_flags = SA_NODEFER;
129 sa.sa_sigaction = handle_signal;
130
131 sigaction(SIGSEGV, &sa, nullptr);
132 sigaction(SIGFPE, &sa, nullptr);
133
134 std::set_terminate(handle_terminate);
135 }
136
137 if (sigint_handlers)
138 {
139 struct sigaction shutdown{};
140 shutdown.sa_handler = sigint_signal_handler;
141 sigemptyset(&shutdown.sa_mask);
142 shutdown.sa_flags = 0;
143
144 sigaction(SIGINT, &shutdown, nullptr);
145 sigaction(SIGTERM, &shutdown, nullptr);
146 }
147}
148#endif
149
150void crash_signal_handler(int sig)
151{
152 fail("Severe error occurred", sig);
153 sigjmp_buf* jump_point = get_current_jump_point_ptr();
154 if (jump_point) siglongjmp(*jump_point, 1);
155 std::abort();
156}
157
158void sigint_signal_handler(int sig)
159{
160 std::vector<Hook> &sigint_hooks = get_sigint_hooks();
161 std::lock_guard<std::mutex> lock(get_sigint_hook_mutex());
162 for (auto &hook : sigint_hooks)
163 {
164 try
165 {
166 hook(sig);
167 }
168 catch (...)
169 {
170 }
171 }
172}
173
174void register_sigint_hook(Hook hook)
175{
176 std::vector<Hook> &sigint_hooks = get_sigint_hooks();
177 std::lock_guard<std::mutex> lock(get_sigint_hook_mutex());
178 sigint_hooks.push_back(std::move(hook));
179}
static ErrorState & get_error_state()
Get the error state instance.
Error state container for sharing between libraries.