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 || signal == SIGSEGV || signal == SIGTRAP;
50 }
51
IsSignalPidAvaliable(int32_t sigCode)52 bool SignalInfo::IsSignalPidAvaliable(int32_t sigCode)
53 {
54 switch (sigCode) {
55 case SI_USER:
56 case SI_QUEUE:
57 case SI_TIMER:
58 case SI_ASYNCIO:
59 case SI_MESGQ:
60 return true;
61 default:
62 return false;
63 }
64 }
65
FormatSignalName(int32_t signal)66 std::string SignalInfo::FormatSignalName(int32_t signal)
67 {
68 switch (signal) {
69 case SIGABRT:
70 return "SIGABRT";
71 case SIGALRM:
72 return "SIGALRM";
73 case SIGBUS:
74 return "SIGBUS";
75 case SIGFPE:
76 return "SIGFPE";
77 case SIGILL:
78 return "SIGILL";
79 case SIGSEGV:
80 return "SIGSEGV";
81 case SIGSYS:
82 return "SIGSYS";
83 case SIGTRAP:
84 return "SIGTRAP";
85 default:
86 return "Uncare Signal";
87 }
88 }
89
FormatSIGBUSCodeName(int32_t signalCode)90 std::string SignalInfo::FormatSIGBUSCodeName(int32_t signalCode)
91 {
92 std::stringstream codeName;
93 switch (signalCode) {
94 case BUS_ADRALN:
95 codeName << "BUS_ADRALN";
96 break;
97 case BUS_ADRERR:
98 codeName << "BUS_ADRERR";
99 break;
100 case BUS_OBJERR:
101 codeName << "BUS_OBJERR";
102 break;
103 case BUS_MCEERR_AR:
104 codeName << "BUS_MCEERR_AR";
105 break;
106 case BUS_MCEERR_AO:
107 codeName << "BUS_MCEERR_AO";
108 break;
109 default:
110 codeName << FormatCommonSignalCodeName(signalCode);
111 break;
112 }
113 return codeName.str();
114 }
115
FormatSIGILLCodeName(int32_t signalCode)116 std::string SignalInfo::FormatSIGILLCodeName(int32_t signalCode)
117 {
118 std::stringstream codeName;
119 switch (signalCode) {
120 case ILL_ILLOPC:
121 codeName << "ILL_ILLOPC";
122 break;
123 case ILL_ILLOPN:
124 codeName << "ILL_ILLOPN";
125 break;
126 case ILL_ILLADR:
127 codeName << "ILL_ILLADR";
128 break;
129 case ILL_ILLTRP:
130 codeName << "ILL_ILLTRP";
131 break;
132 case ILL_PRVOPC:
133 codeName << "ILL_PRVOPC";
134 break;
135 case ILL_PRVREG:
136 codeName << "ILL_PRVREG";
137 break;
138 case ILL_COPROC:
139 codeName << "ILL_COPROC";
140 break;
141 case ILL_BADSTK:
142 codeName << "ILL_BADSTK";
143 break;
144 default:
145 codeName << FormatCommonSignalCodeName(signalCode);
146 break;
147 }
148 return codeName.str();
149 }
150
FormatSIGFPECodeName(int32_t signalCode)151 std::string SignalInfo::FormatSIGFPECodeName(int32_t signalCode)
152 {
153 std::stringstream codeName;
154 switch (signalCode) {
155 case FPE_INTDIV:
156 codeName << "FPE_INTDIV";
157 break;
158 case FPE_INTOVF:
159 codeName << "FPE_INTOVF";
160 break;
161 case FPE_FLTDIV:
162 codeName << "FPE_FLTDIV";
163 break;
164 case FPE_FLTOVF:
165 codeName << "FPE_FLTOVF";
166 break;
167 case FPE_FLTUND:
168 codeName << "FPE_FLTUND";
169 break;
170 case FPE_FLTRES:
171 codeName << "FPE_FLTRES";
172 break;
173 case FPE_FLTINV:
174 codeName << "FPE_FLTINV";
175 break;
176 case FPE_FLTSUB:
177 codeName << "FPE_FLTSUB";
178 break;
179 default:
180 codeName << FormatCommonSignalCodeName(signalCode);
181 break;
182 }
183 return codeName.str();
184 }
185
FormatSIGSEGVCodeName(int32_t signalCode)186 std::string SignalInfo::FormatSIGSEGVCodeName(int32_t signalCode)
187 {
188 std::stringstream codeName;
189 switch (signalCode) {
190 case SEGV_MAPERR:
191 codeName << "SEGV_MAPERR";
192 break;
193 case SEGV_ACCERR:
194 codeName << "SEGV_ACCERR";
195 break;
196 default:
197 codeName << FormatCommonSignalCodeName(signalCode);
198 break;
199 }
200 return codeName.str();
201 }
202
FormatSIGTRAPCodeName(int32_t signalCode)203 std::string SignalInfo::FormatSIGTRAPCodeName(int32_t signalCode)
204 {
205 std::stringstream codeName;
206 switch (signalCode) {
207 case TRAP_BRKPT:
208 codeName << "TRAP_BRKPT";
209 break;
210 case TRAP_TRACE:
211 codeName << "TRAP_TRACE";
212 break;
213 case TRAP_BRANCH:
214 codeName << "TRAP_BRANCH";
215 break;
216 case TRAP_HWBKPT:
217 codeName << "TRAP_HWBKPT";
218 break;
219 default:
220 codeName << FormatCommonSignalCodeName(signalCode);
221 break;
222 }
223 return codeName.str();
224 }
225
FormatCommonSignalCodeName(int32_t signalCode)226 std::string SignalInfo::FormatCommonSignalCodeName(int32_t signalCode)
227 {
228 std::stringstream codeName;
229 switch (signalCode) {
230 case SI_USER:
231 codeName << "SI_USER";
232 break;
233 case SI_KERNEL:
234 codeName << "SI_KERNEL";
235 break;
236 case SI_QUEUE:
237 codeName << "SI_QUEUE";
238 break;
239 case SI_TIMER:
240 codeName << "SI_TIMER";
241 break;
242 case SI_MESGQ:
243 codeName << "SI_MESGQ";
244 break;
245 case SI_ASYNCIO:
246 codeName << "SI_ASYNCIO";
247 break;
248 case SI_SIGIO:
249 codeName << "SI_SIGIO";
250 break;
251 case SI_TKILL:
252 codeName << "SI_TKILL";
253 break;
254 default:
255 codeName << "Unknown Code:" << signalCode;
256 break;
257 }
258 return codeName.str();
259 }
260
FormatCodeName(int32_t signal,int32_t signalCode)261 std::string SignalInfo::FormatCodeName(int32_t signal, int32_t signalCode)
262 {
263 switch (signal) {
264 case SIGILL:
265 return FormatSIGILLCodeName(signalCode);
266 case SIGBUS:
267 return FormatSIGBUSCodeName(signalCode);
268 case SIGFPE:
269 return FormatSIGFPECodeName(signalCode);
270 case SIGSEGV:
271 return FormatSIGSEGVCodeName(signalCode);
272 case SIGTRAP:
273 return FormatSIGTRAPCodeName(signalCode);
274 default:
275 break;
276 }
277 return FormatCommonSignalCodeName(signalCode);
278 }
279 } // namespace HiviewDFX
280 } // namespace OHOS
281