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