master
c 267 lines 10 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "signal-code.h"
4 #include "libnetdata/libnetdata.h"
5
6 #define SIG_NOT_FOUND 0xFFFFFFF
7
8 // --------------------------------------------------------------------------------------------------------------------
9
10 typedef int SIGNAL_NUM;
11
12 ENUM_STR_MAP_DEFINE(SIGNAL_NUM) = {
13 { SIGHUP, "SIGHUP" }, // 1 Hangup.
14 { SIGINT, "SIGINT" }, // 2 Interactive attention signal.
15 { SIGQUIT, "SIGQUIT" }, // 3 Quit.
16 { SIGILL, "SIGILL" }, // 4 Illegal instruction.
17 { SIGTRAP, "SIGTRAP" }, // 5 Trace/breakpoint trap.
18 { SIGABRT, "SIGABRT" }, // 6 Abnormal termination.
19 { SIGBUS, "SIGBUS" }, // 7 Bus error.
20 { SIGFPE, "SIGFPE" }, // 8 Erroneous arithmetic operation.
21 { SIGKILL, "SIGKILL" }, // 9 Killed.
22 { SIGUSR1, "SIGUSR1" }, // 10 User-defined signal 1.
23 { SIGSEGV, "SIGSEGV" }, // 11 Invalid access to storage.
24 { SIGUSR2, "SIGUSR2" }, // 12 User-defined signal 2.
25 { SIGPIPE, "SIGPIPE" }, // 13 Broken pipe.
26 { SIGALRM, "SIGALRM" }, // 14 Alarm clock.
27 { SIGTERM, "SIGTERM" }, // 15 Termination request.
28 #ifdef SIGSTKFLT
29 { SIGSTKFLT, "SIGSTKFLT" }, // 16 Stack fault (obsolete).
30 #endif
31 { SIGCHLD, "SIGCHLD" }, // 17 Child terminated or stopped.
32 { SIGCONT, "SIGCONT" }, // 18 Continue.
33 { SIGSTOP, "SIGSTOP" }, // 19 Stop, unblockable.
34 { SIGTSTP, "SIGTSTP" }, // 20 Keyboard stop.
35 { SIGTTIN, "SIGTTIN" }, // 21 Background read from control terminal.
36 { SIGTTOU, "SIGTTOU" }, // 22 Background write to control terminal.
37 { SIGURG, "SIGURG" }, // 23 Urgent data is available at a socket.
38 { SIGXCPU, "SIGXCPU" }, // 24 CPU time limit exceeded.
39 { SIGXFSZ, "SIGXFSZ" }, // 25 File size limit exceeded.
40 { SIGVTALRM, "SIGVTALRM" }, // 26 Virtual timer expired.
41 { SIGPROF, "SIGPROF" }, // 27 Profiling timer expired.
42 { SIGWINCH, "SIGWINCH" }, // 28 Window size change (4.3 BSD, Sun).
43 #ifdef SIGPOLL
44 { SIGPOLL, "SIGPOLL" }, // 29 Pollable event occurred (System V).
45 #endif
46 #ifdef SIGPWR
47 { SIGPWR, "SIGPWR" }, // 30 Power failure imminent.
48 #endif
49 { SIGSYS, "SIGSYS" }, // 31 Bad system call.
50
51 // Terminator
52 { 0, NULL },
53 };
54
55 // IMPORTANT: These function return invalid values when the signal is not found - always use a function wrapper
56 ENUM_STR_DEFINE_FUNCTIONS(SIGNAL_NUM, SIG_NOT_FOUND, NULL);
57
58 // --------------------------------------------------------------------------------------------------------------------
59
60 typedef int SI_CODE;
61
62 ENUM_STR_MAP_DEFINE(SI_CODE) = {
63 #ifdef SI_ASYNCNL
64 { SI_ASYNCNL, "SI_ASYNCNL" },
65 #endif
66 #ifdef SI_DETHREAD
67 { SI_DETHREAD, "SI_DETHREAD" },
68 #endif
69 #ifdef SI_TKILL
70 { SI_TKILL, "SI_TKILL" },
71 #endif
72 #ifdef SI_SIGIO
73 { SI_SIGIO, "SI_SIGIO" },
74 #endif
75 { SI_ASYNCIO, "SI_ASYNCIO" },
76 { SI_MESGQ, "SI_MESGQ" },
77 { SI_TIMER, "SI_TIMER" },
78 { SI_QUEUE, "SI_QUEUE" },
79 { SI_USER, "SI_USER" },
80 #ifdef SI_KERNEL
81 { SI_KERNEL, "SI_KERNEL" },
82 #endif
83
84 // Terminator
85 {0, NULL},
86 };
87
88 // IMPORTANT: These function return invalid values when the signal is not found - always use a function wrapper
89 ENUM_STR_DEFINE_FUNCTIONS(SI_CODE, SIG_NOT_FOUND, NULL);
90
91 // --------------------------------------------------------------------------------------------------------------------
92
93 // Helper macro to create a SIGNAL_CODE value
94 #define SIGNAL_CODE_CREATE(signo, si_code) (((uint64_t)(signo) << 32) | (uint32_t)(si_code))
95
96 // Define mapping from SIGNAL_CODE to string representation
97 ENUM_STR_MAP_DEFINE(SIGNAL_CODE) = {
98 // SIGILL codes
99 { SIGNAL_CODE_CREATE(SIGILL, ILL_ILLOPC), "ILL_ILLOPC" }, // Illegal opcode
100 { SIGNAL_CODE_CREATE(SIGILL, ILL_ILLOPN), "ILL_ILLOPN" }, // Illegal operand
101 { SIGNAL_CODE_CREATE(SIGILL, ILL_ILLADR), "ILL_ILLADR" }, // Illegal addressing mode
102 { SIGNAL_CODE_CREATE(SIGILL, ILL_ILLTRP), "ILL_ILLTRP" }, // Illegal trap
103 { SIGNAL_CODE_CREATE(SIGILL, ILL_PRVOPC), "ILL_PRVOPC" }, // Privileged opcode
104 { SIGNAL_CODE_CREATE(SIGILL, ILL_PRVREG), "ILL_PRVREG" }, // Privileged register
105 { SIGNAL_CODE_CREATE(SIGILL, ILL_COPROC), "ILL_COPROC" }, // Coprocessor error
106 { SIGNAL_CODE_CREATE(SIGILL, ILL_BADSTK), "ILL_BADSTK" }, // Internal stack error
107 #ifdef ILL_BADIADDR
108 { SIGNAL_CODE_CREATE(SIGILL, ILL_BADIADDR), "ILL_BADIADDR" }, // Unimplemented instruction address
109 #endif
110
111 // SIGFPE codes
112 { SIGNAL_CODE_CREATE(SIGFPE, FPE_INTDIV), "FPE_INTDIV" }, // Integer divide by zero
113 { SIGNAL_CODE_CREATE(SIGFPE, FPE_INTOVF), "FPE_INTOVF" }, // Integer overflow
114 { SIGNAL_CODE_CREATE(SIGFPE, FPE_FLTDIV), "FPE_FLTDIV" }, // Floating point divide by zero
115 { SIGNAL_CODE_CREATE(SIGFPE, FPE_FLTOVF), "FPE_FLTOVF" }, // Floating point overflow
116 { SIGNAL_CODE_CREATE(SIGFPE, FPE_FLTUND), "FPE_FLTUND" }, // Floating point underflow
117 { SIGNAL_CODE_CREATE(SIGFPE, FPE_FLTRES), "FPE_FLTRES" }, // Floating point inexact result
118 { SIGNAL_CODE_CREATE(SIGFPE, FPE_FLTINV), "FPE_FLTINV" }, // Floating point invalid operation
119 { SIGNAL_CODE_CREATE(SIGFPE, FPE_FLTSUB), "FPE_FLTSUB" }, // Subscript out of range
120 #ifdef FPE_FLTUNK
121 { SIGNAL_CODE_CREATE(SIGFPE, FPE_FLTUNK), "FPE_FLTUNK" }, // Undiagnosed floating-point exception
122 #endif
123 #ifdef FPE_CONDTRAP
124 { SIGNAL_CODE_CREATE(SIGFPE, FPE_CONDTRAP), "FPE_CONDTRAP" }, // Trap on condition
125 #endif
126
127 // SIGSEGV codes
128 { SIGNAL_CODE_CREATE(SIGSEGV, SEGV_MAPERR), "SEGV_MAPERR" }, // Address not mapped to object
129 { SIGNAL_CODE_CREATE(SIGSEGV, SEGV_ACCERR), "SEGV_ACCERR" }, // Invalid permissions for mapped object
130 #ifdef SEGV_BNDERR
131 { SIGNAL_CODE_CREATE(SIGSEGV, SEGV_BNDERR), "SEGV_BNDERR" }, // Bounds checking failure
132 #endif
133 #ifdef SEGV_PKUERR
134 { SIGNAL_CODE_CREATE(SIGSEGV, SEGV_PKUERR), "SEGV_PKUERR" }, // Protection key checking failure
135 #endif
136 #ifdef SEGV_ACCADI
137 { SIGNAL_CODE_CREATE(SIGSEGV, SEGV_ACCADI), "SEGV_ACCADI" }, // ADI not enabled for mapped object
138 #endif
139 #ifdef SEGV_ADIDERR
140 { SIGNAL_CODE_CREATE(SIGSEGV, SEGV_ADIDERR), "SEGV_ADIDERR" }, // Disrupting MCD error
141 #endif
142 #ifdef SEGV_ADIPERR
143 { SIGNAL_CODE_CREATE(SIGSEGV, SEGV_ADIPERR), "SEGV_ADIPERR" }, // Precise MCD exception
144 #endif
145 #ifdef SEGV_MTEAERR
146 { SIGNAL_CODE_CREATE(SIGSEGV, SEGV_MTEAERR), "SEGV_MTEAERR" }, // Asynchronous ARM MTE error
147 #endif
148 #ifdef SEGV_MTESERR
149 { SIGNAL_CODE_CREATE(SIGSEGV, SEGV_MTESERR), "SEGV_MTESERR" }, // Synchronous ARM MTE exception
150 #endif
151 #ifdef SEGV_CPERR
152 { SIGNAL_CODE_CREATE(SIGSEGV, SEGV_CPERR), "SEGV_CPERR" }, // Control protection fault
153 #endif
154
155 // SIGBUS codes
156 { SIGNAL_CODE_CREATE(SIGBUS, BUS_ADRALN), "BUS_ADRALN" }, // Invalid address alignment
157 { SIGNAL_CODE_CREATE(SIGBUS, BUS_ADRERR), "BUS_ADRERR" }, // Non-existent physical address
158 { SIGNAL_CODE_CREATE(SIGBUS, BUS_OBJERR), "BUS_OBJERR" }, // Object specific hardware error
159 #ifdef BUS_MCEERR_AR
160 { SIGNAL_CODE_CREATE(SIGBUS, BUS_MCEERR_AR), "BUS_MCEERR_AR" }, // Hardware memory error: action required
161 #endif
162 #ifdef BUS_MCEERR_AO
163 { SIGNAL_CODE_CREATE(SIGBUS, BUS_MCEERR_AO), "BUS_MCEERR_AO" }, // Hardware memory error: action optional
164 #endif
165
166 // SIGTRAP codes
167 #ifdef TRAP_BRKPT
168 { SIGNAL_CODE_CREATE(SIGTRAP, TRAP_BRKPT), "TRAP_BRKPT" }, // Process breakpoint
169 #endif
170 #ifdef TRAP_TRACE
171 { SIGNAL_CODE_CREATE(SIGTRAP, TRAP_TRACE), "TRAP_TRACE" }, // Process trace trap
172 #endif
173 #ifdef TRAP_BRANCH
174 { SIGNAL_CODE_CREATE(SIGTRAP, TRAP_BRANCH), "TRAP_BRANCH" }, // Process taken branch trap
175 #endif
176 #ifdef TRAP_HWBKPT
177 { SIGNAL_CODE_CREATE(SIGTRAP, TRAP_HWBKPT), "TRAP_HWBKPT" }, // Hardware breakpoint/watchpoint
178 #endif
179 #ifdef TRAP_UNK
180 { SIGNAL_CODE_CREATE(SIGTRAP, TRAP_UNK), "TRAP_UNK" }, // Undiagnosed trap
181 #endif
182
183 // Terminator
184 { 0, NULL },
185 };
186
187 // IMPORTANT: These function return invalid values when the signal is not found - always use a function wrapper
188 ENUM_STR_DEFINE_FUNCTIONS(SIGNAL_CODE, SIG_NOT_FOUND, NULL);
189
190 // --------------------------------------------------------------------------------------------------------------------
191
192 void SIGNAL_CODE_2str_h(SIGNAL_CODE code, char *buf, size_t size) {
193 if(!buf || !size) return;
194 if(size < 3 || code == 0) {
195 buf[0] = '\0';
196 return;
197 }
198
199 char b1[UINT64_MAX_LENGTH];
200 char b2[UINT64_MAX_LENGTH];
201
202 int signo = SIGNAL_CODE_GET_SIGNO(code);
203 int si_code = SIGNAL_CODE_GET_SI_CODE(code);
204
205 // find the string for the signal
206 const char *signo_str = SIGNAL_NUM_2str(signo);
207 if(!signo_str || !*signo_str) {
208 print_int64(b1, signo);
209 signo_str = b1;
210 }
211
212 // find the string for the si_code
213 const char *si_code_str = SIGNAL_CODE_2str(code);
214 if(!si_code_str || !*si_code_str) {
215 si_code_str = SI_CODE_2str(si_code);
216 if(!si_code_str || !*si_code_str) {
217 print_int64(b2, si_code);
218 si_code_str = b2;
219 }
220 }
221
222 // now we have to concatenate the two strings
223 // with a slash in between
224
225 strncpyz(buf, signo_str, size - 1);
226 size_t len = strlen(buf);
227
228 if(size - 1 > len)
229 buf[len++] = '/';
230
231 if(size -1 > len)
232 strncpyz(&buf[len], si_code_str, size - 1 - len);
233
234 buf[size - 1] = '\0';
235 }
236
237 SIGNAL_CODE SIGNAL_CODE_2id_h(const char *str) {
238 if(!str || !*str) return 0;
239
240 CLEAN_CHAR_P *buf = strdupz(str);
241
242 char *si_code_str = strchr(buf, '/');
243 if(si_code_str) {
244 *si_code_str = '\0';
245 si_code_str++;
246 }
247
248 int signo = SIGNAL_NUM_2id(buf);
249 if(signo == SIG_NOT_FOUND)
250 signo = str2i(buf);
251
252 SIGNAL_CODE code = si_code_str ? SIGNAL_CODE_2id(si_code_str) : SIG_NOT_FOUND;
253 if(code != SIG_NOT_FOUND)
254 // this has both signo and si_code in it
255 return code;
256
257 int si_code = si_code_str ? SI_CODE_2id(si_code_str) : SIG_NOT_FOUND;
258 if(si_code == SIG_NOT_FOUND)
259 si_code = si_code_str ? str2i(si_code_str) : 0;
260
261 return SIGNAL_CODE_CREATE(signo, si_code);
262 }
263
264 // Function to create a SIGNAL_CODE from signal number and signal code
265 SIGNAL_CODE signal_code(int signo, int si_code) {
266 return SIGNAL_CODE_CREATE(signo, si_code);
267 }