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