1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "signal_info.h"
17
18 #include <csignal>
19 #include <iomanip>
20 #include <sstream>
21
22 namespace OHOS {
23 namespace HiviewDFX {
FormatSignalInfo(std::stringstream & ss,const siginfo_t & siginfo)24 void SignalInfo::FormatSignalInfo(std::stringstream &ss, const siginfo_t &siginfo)
25 {
26 int32_t signo = siginfo.si_signo;
27 int32_t code = siginfo.si_code;
28 ss << "Signal:" << FormatSignalName(signo) << "(" << FormatCodeName(signo, code) << ")";
29 if (IsSignalAddrAvaliable(signo)) {
30 ss << "@" << std::setw(8) << std::setfill('0') << std::hex << siginfo.si_addr << " "; // 8 : bit width
31 }
32
33 if (SI_FROMUSER(&siginfo) && (siginfo.si_pid != 0)) {
34 ss << "form:" << std::to_string(siginfo.si_pid) << ":" << std::to_string(siginfo.si_uid);
35 }
36 }
37
IsSignalInfoAvaliable(int32_t signal)38 bool SignalInfo::IsSignalInfoAvaliable(int32_t signal)
39 {
40 struct sigaction previousAction;
41 if (sigaction(signal, nullptr, &previousAction) < 0) {
42 return false;
43 }
44 return (static_cast<uint32_t>(previousAction.sa_flags) & SA_SIGINFO) != 0;
45 }
46
IsSignalAddrAvaliable(int32_t signal)47 bool SignalInfo::IsSignalAddrAvaliable(int32_t signal)
48 {
49 return ((signal == SIGABRT) || (signal == SIGBUS) || (signal == SIGILL)
50 || (signal == SIGSEGV) || (signal == SIGTRAP));
51 }
52
IsSignalPidAvaliable(int32_t sigCode)53 bool SignalInfo::IsSignalPidAvaliable(int32_t sigCode)
54 {
55 switch (sigCode) {
56 case SI_USER:
57 case SI_QUEUE:
58 case SI_TIMER:
59 case SI_ASYNCIO:
60 case SI_MESGQ:
61 return true;
62 default:
63 return false;
64 }
65 }
66
FormatSignalName(int32_t signal)67 std::string SignalInfo::FormatSignalName(int32_t signal)
68 {
69 switch (signal) {
70 case SIGABRT:
71 return "SIGABRT";
72 case SIGALRM:
73 return "SIGALRM";
74 case SIGBUS:
75 return "SIGBUS";
76 case SIGFPE:
77 return "SIGFPE";
78 case SIGILL:
79 return "SIGILL";
80 case SIGSEGV:
81 return "SIGSEGV";
82 case SIGSYS:
83 return "SIGSYS";
84 case SIGTRAP:
85 return "SIGTRAP";
86 default:
87 return "Uncare Signal";
88 }
89 }
90
FormatSIGBUSCodeName(int32_t signalCode)91 std::string SignalInfo::FormatSIGBUSCodeName(int32_t signalCode)
92 {
93 std::stringstream codeName;
94 switch (signalCode) {
95 case BUS_ADRALN:
96 codeName << "BUS_ADRALN";
97 break;
98 case BUS_ADRERR:
99 codeName << "BUS_ADRERR";
100 break;
101 case BUS_OBJERR:
102 codeName << "BUS_OBJERR";
103 break;
104 case BUS_MCEERR_AR:
105 codeName << "BUS_MCEERR_AR";
106 break;
107 case BUS_MCEERR_AO:
108 codeName << "BUS_MCEERR_AO";
109 break;
110 default:
111 codeName << FormatCommonSignalCodeName(signalCode);
112 break;
113 }
114 return codeName.str();
115 }
116
FormatSIGILLCodeName(int32_t signalCode)117 std::string SignalInfo::FormatSIGILLCodeName(int32_t signalCode)
118 {
119 std::stringstream codeName;
120 switch (signalCode) {
121 case ILL_ILLOPC:
122 codeName << "ILL_ILLOPC";
123 break;
124 case ILL_ILLOPN:
125 codeName << "ILL_ILLOPN";
126 break;
127 case ILL_ILLADR:
128 codeName << "ILL_ILLADR";
129 break;
130 case ILL_ILLTRP:
131 codeName << "ILL_ILLTRP";
132 break;
133 case ILL_PRVOPC:
134 codeName << "ILL_PRVOPC";
135 break;
136 case ILL_PRVREG:
137 codeName << "ILL_PRVREG";
138 break;
139 case ILL_COPROC:
140 codeName << "ILL_COPROC";
141 break;
142 case ILL_BADSTK:
143 codeName << "ILL_BADSTK";
144 break;
145 default:
146 codeName << FormatCommonSignalCodeName(signalCode);
147 break;
148 }
149 return codeName.str();
150 }
151
FormatSIGFPECodeName(int32_t signalCode)152 std::string SignalInfo::FormatSIGFPECodeName(int32_t signalCode)
153 {
154 std::stringstream codeName;
155 switch (signalCode) {
156 case FPE_INTDIV:
157 codeName << "FPE_INTDIV";
158 break;
159 case FPE_INTOVF:
160 codeName << "FPE_INTOVF";
161 break;
162 case FPE_FLTDIV:
163 codeName << "FPE_FLTDIV";
164 break;
165 case FPE_FLTOVF:
166 codeName << "FPE_FLTOVF";
167 break;
168 case FPE_FLTUND:
169 codeName << "FPE_FLTUND";
170 break;
171 case FPE_FLTRES:
172 codeName << "FPE_FLTRES";
173 break;
174 case FPE_FLTINV:
175 codeName << "FPE_FLTINV";
176 break;
177 case FPE_FLTSUB:
178 codeName << "FPE_FLTSUB";
179 break;
180 default:
181 codeName << FormatCommonSignalCodeName(signalCode);
182 break;
183 }
184 return codeName.str();
185 }
186
FormatSIGSEGVCodeName(int32_t signalCode)187 std::string SignalInfo::FormatSIGSEGVCodeName(int32_t signalCode)
188 {
189 std::stringstream codeName;
190 switch (signalCode) {
191 case SEGV_MAPERR:
192 codeName << "SEGV_MAPERR";
193 break;
194 case SEGV_ACCERR:
195 codeName << "SEGV_ACCERR";
196 break;
197 default:
198 codeName << FormatCommonSignalCodeName(signalCode);
199 break;
200 }
201 return codeName.str();
202 }
203
FormatSIGTRAPCodeName(int32_t signalCode)204 std::string SignalInfo::FormatSIGTRAPCodeName(int32_t signalCode)
205 {
206 std::stringstream codeName;
207 switch (signalCode) {
208 case TRAP_BRKPT:
209 codeName << "TRAP_BRKPT";
210 break;
211 case TRAP_TRACE:
212 codeName << "TRAP_TRACE";
213 break;
214 case TRAP_BRANCH:
215 codeName << "TRAP_BRANCH";
216 break;
217 case TRAP_HWBKPT:
218 codeName << "TRAP_HWBKPT";
219 break;
220 default:
221 codeName << FormatCommonSignalCodeName(signalCode);
222 break;
223 }
224 return codeName.str();
225 }
226
FormatCommonSignalCodeName(int32_t signalCode)227 std::string SignalInfo::FormatCommonSignalCodeName(int32_t signalCode)
228 {
229 std::stringstream codeName;
230 switch (signalCode) {
231 case SI_USER:
232 codeName << "SI_USER";
233 break;
234 case SI_KERNEL:
235 codeName << "SI_KERNEL";
236 break;
237 case SI_QUEUE:
238 codeName << "SI_QUEUE";
239 break;
240 case SI_TIMER:
241 codeName << "SI_TIMER";
242 break;
243 case SI_MESGQ:
244 codeName << "SI_MESGQ";
245 break;
246 case SI_ASYNCIO:
247 codeName << "SI_ASYNCIO";
248 break;
249 case SI_SIGIO:
250 codeName << "SI_SIGIO";
251 break;
252 case SI_TKILL:
253 codeName << "SI_TKILL";
254 break;
255 default:
256 codeName << "Unknown Code:" << signalCode;
257 break;
258 }
259 return codeName.str();
260 }
261
FormatCodeName(int32_t signal,int32_t signalCode)262 std::string SignalInfo::FormatCodeName(int32_t signal, int32_t signalCode)
263 {
264 switch (signal) {
265 case SIGILL:
266 return FormatSIGILLCodeName(signalCode);
267 case SIGBUS:
268 return FormatSIGBUSCodeName(signalCode);
269 case SIGFPE:
270 return FormatSIGFPECodeName(signalCode);
271 case SIGSEGV:
272 return FormatSIGSEGVCodeName(signalCode);
273 case SIGTRAP:
274 return FormatSIGTRAPCodeName(signalCode);
275 default:
276 break;
277 }
278 return FormatCommonSignalCodeName(signalCode);
279 }
280 } // namespace HiviewDFX
281 } // namespace OHOS
282