• 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 <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