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