1 /*
2 * Copyright (c) 2021-2023 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 "dfx_signal.h"
17
18 #include <map>
19 #include <string>
20 #include "dfx_define.h"
21 #include "dfx_log.h"
22 #include "string_printf.h"
23
24 namespace OHOS {
25 namespace HiviewDFX {
26 namespace {
27 #undef LOG_DOMAIN
28 #undef LOG_TAG
29 #define LOG_DOMAIN 0xD002D11
30 #define LOG_TAG "DfxSignal"
31 }
32
IsAvailable() const33 bool DfxSignal::IsAvailable() const
34 {
35 struct sigaction prevAction;
36 if (sigaction(signal_, nullptr, &prevAction) < 0) {
37 return 0;
38 }
39 return static_cast<unsigned int>(prevAction.sa_flags) & SA_SIGINFO;
40 }
41
IsAddrAvailable() const42 bool DfxSignal::IsAddrAvailable() const
43 {
44 switch (signal_) {
45 case SIGABRT:
46 case SIGBUS:
47 case SIGILL:
48 case SIGSEGV:
49 case SIGTRAP:
50 return true;
51 default:
52 return false;
53 }
54 }
55
IsPidAvailable() const56 bool DfxSignal::IsPidAvailable() const
57 {
58 switch (signal_) {
59 case SI_USER:
60 case SI_QUEUE:
61 case SI_TIMER:
62 case SI_ASYNCIO:
63 case SI_MESGQ:
64 return true;
65 default:
66 return false;
67 }
68 }
69
PrintSignal(const siginfo_t & info)70 std::string DfxSignal::PrintSignal(const siginfo_t &info)
71 {
72 std::string sigString = StringPrintf("Signal:%s(%s)", FormatSignalName(info.si_signo).c_str(),\
73 FormatCodeName(info.si_signo, info.si_code).c_str());
74
75 DfxSignal signal(info.si_signo);
76 if (signal.IsAddrAvailable()) {
77 sigString = sigString + StringPrintf("@%" PRIX64_ADDR " ", (uint64_t)info.si_addr);
78 }
79
80 if ((info.si_code <= 0) && (info.si_pid != 0)) {
81 sigString = sigString + StringPrintf("from:%d:%u", info.si_pid, info.si_uid);
82 }
83
84 return sigString;
85 }
86
FormatSignalName(const int32_t signal)87 std::string DfxSignal::FormatSignalName(const int32_t signal)
88 {
89 std::map<int32_t, std::string> sigMaps = {
90 { SIGILL, std::string("SIGILL") },
91 { SIGTRAP, std::string("SIGTRAP") },
92 { SIGABRT, std::string("SIGABRT") },
93 { SIGALRM, std::string("SIGALRM") },
94 { SIGBUS, std::string("SIGBUS") },
95 { SIGFPE, std::string("SIGFPE") },
96 { SIGSEGV, std::string("SIGSEGV") },
97 { SIGSTKFLT, std::string("SIGSTKFLT") },
98 { SIGSYS, std::string("SIGSYS") },
99 { SIGDUMP, std::string("SIGDUMP") },
100 { SIGLEAK_STACK, std::string("DEBUG SIGNAL") },
101 };
102
103 if (sigMaps.find(signal) != sigMaps.end()) {
104 return sigMaps[signal];
105 }
106 return "Uncare Signal";
107 }
108
FormatCodeName(const int32_t signal,const int32_t signalCode)109 std::string DfxSignal::FormatCodeName(const int32_t signal, const int32_t signalCode)
110 {
111 switch (signal) {
112 case SIGILL:
113 return FormatSIGILLCodeName(signalCode);
114 case SIGBUS:
115 return FormatSIGBUSCodeName(signalCode);
116 case SIGFPE:
117 return FormatSIGFPECodeName(signalCode);
118 case SIGSEGV:
119 return FormatSIGSEGVCodeName(signalCode);
120 case SIGTRAP:
121 return FormatSIGTRAPCodeName(signalCode);
122 case SIGSYS:
123 return FormatSIGSYSCodeName(signalCode);
124 case SIGLEAK_STACK:
125 return FormatSIGLEAKCodeName(signalCode);
126 default:
127 break;
128 }
129 return DfxSignal::FormatCommonSignalCodeName(signalCode);
130 }
131
FormatSIGBUSCodeName(const int32_t signalCode)132 std::string DfxSignal::FormatSIGBUSCodeName(const int32_t signalCode)
133 {
134 switch (signalCode) {
135 case BUS_ADRALN:
136 return "BUS_ADRALN";
137 case BUS_ADRERR:
138 return "BUS_ADRERR";
139 case BUS_OBJERR:
140 return "BUS_OBJERR";
141 case BUS_MCEERR_AR:
142 return "BUS_MCEERR_AR";
143 case BUS_MCEERR_AO:
144 return "BUS_MCEERR_AO";
145 default:
146 return FormatCommonSignalCodeName(signalCode);
147 }
148 }
149
FormatSIGILLCodeName(const int32_t signalCode)150 std::string DfxSignal::FormatSIGILLCodeName(const int32_t signalCode)
151 {
152 switch (signalCode) {
153 case ILL_ILLOPC:
154 return "ILL_ILLOPC";
155 case ILL_ILLOPN:
156 return "ILL_ILLOPN";
157 case ILL_ILLADR:
158 return "ILL_ILLADR";
159 case ILL_ILLTRP:
160 return "ILL_ILLTRP";
161 case ILL_PRVOPC:
162 return "ILL_PRVOPC";
163 case ILL_PRVREG:
164 return "ILL_PRVREG";
165 case ILL_COPROC:
166 return "ILL_COPROC";
167 case ILL_BADSTK:
168 return "ILL_BADSTK";
169 case ILL_ILLPACCFI:
170 return "ILL_ILLPACCFI";
171 default:
172 return FormatCommonSignalCodeName(signalCode);
173 }
174 }
175
FormatSIGFPECodeName(const int32_t signalCode)176 std::string DfxSignal::FormatSIGFPECodeName(const int32_t signalCode)
177 {
178 switch (signalCode) {
179 case FPE_INTDIV:
180 return "FPE_INTDIV";
181 case FPE_INTOVF:
182 return "FPE_INTOVF";
183 case FPE_FLTDIV:
184 return "FPE_FLTDIV";
185 case FPE_FLTOVF:
186 return "FPE_FLTOVF";
187 case FPE_FLTUND:
188 return "FPE_FLTUND";
189 case FPE_FLTRES:
190 return "FPE_FLTRES";
191 case FPE_FLTINV:
192 return "FPE_FLTINV";
193 case FPE_FLTSUB:
194 return "FPE_FLTSUB";
195 default:
196 return FormatCommonSignalCodeName(signalCode);
197 }
198 }
199
FormatSIGSEGVCodeName(const int32_t signalCode)200 std::string DfxSignal::FormatSIGSEGVCodeName(const int32_t signalCode)
201 {
202 switch (signalCode) {
203 case SEGV_MAPERR:
204 return "SEGV_MAPERR";
205 case SEGV_ACCERR:
206 return "SEGV_ACCERR";
207 default:
208 return FormatCommonSignalCodeName(signalCode);
209 }
210 }
211
FormatSIGTRAPCodeName(const int32_t signalCode)212 std::string DfxSignal::FormatSIGTRAPCodeName(const int32_t signalCode)
213 {
214 switch (signalCode) {
215 case TRAP_BRKPT:
216 return "TRAP_BRKPT";
217 case TRAP_TRACE:
218 return "TRAP_TRACE";
219 case TRAP_BRANCH:
220 return "TRAP_BRANCH";
221 case TRAP_HWBKPT:
222 return "TRAP_HWBKPT";
223 default:
224 return FormatCommonSignalCodeName(signalCode);
225 }
226 }
227
FormatSIGSYSCodeName(const int32_t signalCode)228 std::string DfxSignal::FormatSIGSYSCodeName(const int32_t signalCode)
229 {
230 switch (signalCode) {
231 case SYS_SECCOMP:
232 return "SYS_SECCOMP";
233 default:
234 return FormatCommonSignalCodeName(signalCode);
235 }
236 }
237
FormatSIGLEAKCodeName(const int32_t signalCode)238 std::string DfxSignal::FormatSIGLEAKCodeName(const int32_t signalCode)
239 {
240 switch (signalCode) {
241 case SIGLEAK_STACK_FDSAN:
242 return "FDSAN";
243 case SIGLEAK_STACK_JEMALLOC:
244 return "JEMALLOC";
245 case SIGLEAK_STACK_BADFD:
246 return "BADFD";
247 default:
248 return FormatCommonSignalCodeName(signalCode);
249 }
250 }
251
FormatCommonSignalCodeName(const int32_t signalCode)252 std::string DfxSignal::FormatCommonSignalCodeName(const int32_t signalCode)
253 {
254 switch (signalCode) {
255 case SI_USER:
256 return "SI_USER";
257 case SI_KERNEL:
258 return "SI_KERNEL";
259 case SI_QUEUE:
260 return "SI_QUEUE";
261 case SI_TIMER:
262 return "SI_TIMER";
263 case SI_MESGQ:
264 return "SI_MESGQ";
265 case SI_ASYNCIO:
266 return "SI_ASYNCIO";
267 case SI_SIGIO:
268 return "SI_SIGIO";
269 case SI_TKILL:
270 return "SI_TKILL";
271 default:
272 return "UNKNOWN";
273 }
274 }
275 } // namespace HiviewDFX
276 } // namespace OHOS
277