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