xref: /haiku/src/bin/debug/strace/signals.cpp (revision 445d4fd926c569e7b9ae28017da86280aaecbae2)
1 /*
2  * Copyright 2023, Trung Nguyen, trungnt282910@gmail.com.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <stdio.h>
8 
9 #include <string>
10 
11 #include "signals.h"
12 
13 
14 // signal names
15 static const char *kSignalName[] = {
16 	/*  0 */ "SIG0",
17 	/*  1 */ "SIGHUP",
18 	/*  2 */ "SIGINT",
19 	/*  3 */ "SIGQUIT",
20 	/*  4 */ "SIGILL",
21 	/*  5 */ "SIGCHLD",
22 	/*  6 */ "SIGABRT",
23 	/*  7 */ "SIGPIPE",
24 	/*  8 */ "SIGFPE",
25 	/*  9 */ "SIGKILL",
26 	/* 10 */ "SIGSTOP",
27 	/* 11 */ "SIGSEGV",
28 	/* 12 */ "SIGCONT",
29 	/* 13 */ "SIGTSTP",
30 	/* 14 */ "SIGALRM",
31 	/* 15 */ "SIGTERM",
32 	/* 16 */ "SIGTTIN",
33 	/* 17 */ "SIGTTOU",
34 	/* 18 */ "SIGUSR1",
35 	/* 19 */ "SIGUSR2",
36 	/* 20 */ "SIGWINCH",
37 	/* 21 */ "SIGKILLTHR",
38 	/* 22 */ "SIGTRAP",
39 	/* 23 */ "SIGPOLL",
40 	/* 24 */ "SIGPROF",
41 	/* 25 */ "SIGSYS",
42 	/* 26 */ "SIGURG",
43 	/* 27 */ "SIGVTALRM",
44 	/* 28 */ "SIGXCPU",
45 	/* 29 */ "SIGXFSZ",
46 	/* 30 */ "SIGBUS",
47 	/* 31 */ "SIGRESERVED1",
48 	/* 32 */ "SIGRESERVED2",
49 };
50 
51 
52 std::string
53 signal_name(int signal)
54 {
55 	if (signal >= 0 && signal <= SIGRESERVED2)
56 		return kSignalName[signal];
57 
58 	static char buffer[32];
59 	sprintf(buffer, "%d", signal);
60 	return buffer;
61 }
62 
63 
64 static const char *
65 signal_code(int signal, int code)
66 {
67 #define CASE(X) case X: return #X;
68 	switch (code) {
69 		CASE(SI_USER)
70 		CASE(SI_QUEUE)
71 		CASE(SI_TIMER)
72 		CASE(SI_ASYNCIO)
73 		CASE(SI_MESGQ)
74 	}
75 
76 	switch (signal) {
77 		case SIGILL:
78 			switch (code) {
79 				CASE(ILL_ILLOPC)
80 				CASE(ILL_ILLOPN)
81 				CASE(ILL_ILLADR)
82 				CASE(ILL_ILLTRP)
83 				CASE(ILL_PRVOPC)
84 				CASE(ILL_PRVREG)
85 				CASE(ILL_COPROC)
86 				CASE(ILL_BADSTK)
87 			}
88 			break;
89 		case SIGFPE:
90 			switch (code) {
91 				CASE(FPE_INTDIV)
92 				CASE(FPE_INTOVF)
93 				CASE(FPE_FLTDIV)
94 				CASE(FPE_FLTOVF)
95 				CASE(FPE_FLTUND)
96 				CASE(FPE_FLTRES)
97 				CASE(FPE_FLTINV)
98 				CASE(FPE_FLTSUB)
99 			}
100 			break;
101 		case SIGSEGV:
102 			switch (code) {
103 				CASE(SEGV_MAPERR)
104 				CASE(SEGV_ACCERR)
105 			}
106 			break;
107 		case SIGBUS:
108 			switch (code) {
109 				CASE(BUS_ADRALN)
110 				CASE(BUS_ADRERR)
111 				CASE(BUS_OBJERR)
112 			}
113 			break;
114 		case SIGTRAP:
115 			switch (code) {
116 				CASE(TRAP_BRKPT)
117 				CASE(TRAP_TRACE)
118 			}
119 			break;
120 		case SIGCHLD:
121 			switch (code) {
122 				CASE(CLD_EXITED)
123 				CASE(CLD_KILLED)
124 				CASE(CLD_DUMPED)
125 				CASE(CLD_TRAPPED)
126 				CASE(CLD_STOPPED)
127 				CASE(CLD_CONTINUED)
128 			}
129 			break;
130 		case SIGPOLL:
131 			switch (code) {
132 				CASE(POLL_IN)
133 				CASE(POLL_OUT)
134 				CASE(POLL_MSG)
135 				CASE(POLL_ERR)
136 				CASE(POLL_PRI)
137 				CASE(POLL_HUP)
138 			}
139 			break;
140 	}
141 #undef CASE
142 
143 	static char buffer[32];
144 	sprintf(buffer, "%d", code);
145 	return buffer;
146 }
147 
148 
149 std::string
150 signal_info(siginfo_t& info)
151 {
152 	static char buffer[32];
153 	std::string string;
154 
155 	string.reserve(256);
156 
157 	string += "{";
158 	string += "si_signo=";
159 	string += signal_name(info.si_signo);
160 	string += ", si_code=";
161 	string += signal_code(info.si_signo, info.si_code);
162 
163 	if (info.si_errno != 0) {
164 		string += ", si_errno=0x";
165 		sprintf(buffer, "%x", info.si_errno);
166 		string += buffer;
167 	}
168 
169 	string += ", si_pid=";
170 	sprintf(buffer, "%d", (int)info.si_pid);
171 	string += buffer;
172 	string += ", si_uid=";
173 	sprintf(buffer, "%d", (int)info.si_uid);
174 	string += buffer;
175 
176 	if (info.si_signo == SIGILL || info.si_signo == SIGFPE || info.si_signo == SIGSEGV
177 		|| info.si_signo == SIGBUS || info.si_signo == SIGTRAP) {
178 		string += ", si_addr=";
179 		sprintf(buffer, "%p", info.si_addr);
180 		string += buffer;
181 	}
182 
183 	if (info.si_signo == SIGCHLD) {
184 		string += ", si_status=";
185 		sprintf(buffer, "%d", info.si_status);
186 		string += buffer;
187 	}
188 
189 	if (info.si_signo == SIGPOLL) {
190 		string += ", si_band=";
191 		sprintf(buffer, "%ld", info.si_band);
192 		string += buffer;
193 	}
194 
195 	string += ", si_value=";
196 	sprintf(buffer, "%p", info.si_value.sival_ptr);
197 	string += buffer;
198 	string += "}";
199 
200 	return string;
201 }
202