1020a203aSopenharmony_ci/*
2020a203aSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
3020a203aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4020a203aSopenharmony_ci * you may not use this file except in compliance with the License.
5020a203aSopenharmony_ci * You may obtain a copy of the License at
6020a203aSopenharmony_ci *
7020a203aSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8020a203aSopenharmony_ci *
9020a203aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10020a203aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11020a203aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12020a203aSopenharmony_ci * See the License for the specific language governing permissions and
13020a203aSopenharmony_ci * limitations under the License.
14020a203aSopenharmony_ci */
15020a203aSopenharmony_ci
16020a203aSopenharmony_ci#include "signal_info.h"
17020a203aSopenharmony_ci
18020a203aSopenharmony_ci#include <csignal>
19020a203aSopenharmony_ci#include <iomanip>
20020a203aSopenharmony_ci#include <sstream>
21020a203aSopenharmony_ci
22020a203aSopenharmony_cinamespace OHOS {
23020a203aSopenharmony_cinamespace HiviewDFX {
24020a203aSopenharmony_civoid SignalInfo::FormatSignalInfo(std::stringstream &ss, const siginfo_t &siginfo)
25020a203aSopenharmony_ci{
26020a203aSopenharmony_ci    int32_t signo = siginfo.si_signo;
27020a203aSopenharmony_ci    int32_t code = siginfo.si_code;
28020a203aSopenharmony_ci    ss << "Signal:" << FormatSignalName(signo) << "(" << FormatCodeName(signo, code) << ")";
29020a203aSopenharmony_ci    if (IsSignalAddrAvaliable(signo)) {
30020a203aSopenharmony_ci        ss << "@" << std::setw(8) << std::setfill('0') << std::hex << siginfo.si_addr << " "; // 8 : bit width
31020a203aSopenharmony_ci    }
32020a203aSopenharmony_ci
33020a203aSopenharmony_ci    if (SI_FROMUSER(&siginfo) && (siginfo.si_pid != 0)) {
34020a203aSopenharmony_ci        ss << "form:" << std::to_string(siginfo.si_pid) << ":" << std::to_string(siginfo.si_uid);
35020a203aSopenharmony_ci    }
36020a203aSopenharmony_ci}
37020a203aSopenharmony_ci
38020a203aSopenharmony_cibool SignalInfo::IsSignalInfoAvaliable(int32_t signal)
39020a203aSopenharmony_ci{
40020a203aSopenharmony_ci    struct sigaction previousAction;
41020a203aSopenharmony_ci    if (sigaction(signal, nullptr, &previousAction) < 0) {
42020a203aSopenharmony_ci        return false;
43020a203aSopenharmony_ci    }
44020a203aSopenharmony_ci    return (static_cast<uint32_t>(previousAction.sa_flags) & SA_SIGINFO) != 0;
45020a203aSopenharmony_ci}
46020a203aSopenharmony_ci
47020a203aSopenharmony_cibool SignalInfo::IsSignalAddrAvaliable(int32_t signal)
48020a203aSopenharmony_ci{
49020a203aSopenharmony_ci    return ((signal == SIGABRT) || (signal == SIGBUS) || (signal == SIGILL)
50020a203aSopenharmony_ci        || (signal == SIGSEGV) || (signal == SIGTRAP));
51020a203aSopenharmony_ci}
52020a203aSopenharmony_ci
53020a203aSopenharmony_cibool SignalInfo::IsSignalPidAvaliable(int32_t sigCode)
54020a203aSopenharmony_ci{
55020a203aSopenharmony_ci    switch (sigCode) {
56020a203aSopenharmony_ci        case SI_USER:
57020a203aSopenharmony_ci        case SI_QUEUE:
58020a203aSopenharmony_ci        case SI_TIMER:
59020a203aSopenharmony_ci        case SI_ASYNCIO:
60020a203aSopenharmony_ci        case SI_MESGQ:
61020a203aSopenharmony_ci            return true;
62020a203aSopenharmony_ci        default:
63020a203aSopenharmony_ci            return false;
64020a203aSopenharmony_ci    }
65020a203aSopenharmony_ci}
66020a203aSopenharmony_ci
67020a203aSopenharmony_cistd::string SignalInfo::FormatSignalName(int32_t signal)
68020a203aSopenharmony_ci{
69020a203aSopenharmony_ci    switch (signal) {
70020a203aSopenharmony_ci        case SIGABRT:
71020a203aSopenharmony_ci            return "SIGABRT";
72020a203aSopenharmony_ci        case SIGALRM:
73020a203aSopenharmony_ci            return "SIGALRM";
74020a203aSopenharmony_ci        case SIGBUS:
75020a203aSopenharmony_ci            return "SIGBUS";
76020a203aSopenharmony_ci        case SIGFPE:
77020a203aSopenharmony_ci            return "SIGFPE";
78020a203aSopenharmony_ci        case SIGILL:
79020a203aSopenharmony_ci            return "SIGILL";
80020a203aSopenharmony_ci        case SIGSEGV:
81020a203aSopenharmony_ci            return "SIGSEGV";
82020a203aSopenharmony_ci        case SIGSYS:
83020a203aSopenharmony_ci            return "SIGSYS";
84020a203aSopenharmony_ci        case SIGTRAP:
85020a203aSopenharmony_ci            return "SIGTRAP";
86020a203aSopenharmony_ci        default:
87020a203aSopenharmony_ci            return "Uncare Signal";
88020a203aSopenharmony_ci    }
89020a203aSopenharmony_ci}
90020a203aSopenharmony_ci
91020a203aSopenharmony_cistd::string SignalInfo::FormatSIGBUSCodeName(int32_t signalCode)
92020a203aSopenharmony_ci{
93020a203aSopenharmony_ci    std::stringstream codeName;
94020a203aSopenharmony_ci    switch (signalCode) {
95020a203aSopenharmony_ci        case BUS_ADRALN:
96020a203aSopenharmony_ci            codeName << "BUS_ADRALN";
97020a203aSopenharmony_ci            break;
98020a203aSopenharmony_ci        case BUS_ADRERR:
99020a203aSopenharmony_ci            codeName << "BUS_ADRERR";
100020a203aSopenharmony_ci            break;
101020a203aSopenharmony_ci        case BUS_OBJERR:
102020a203aSopenharmony_ci            codeName << "BUS_OBJERR";
103020a203aSopenharmony_ci            break;
104020a203aSopenharmony_ci        case BUS_MCEERR_AR:
105020a203aSopenharmony_ci            codeName << "BUS_MCEERR_AR";
106020a203aSopenharmony_ci            break;
107020a203aSopenharmony_ci        case BUS_MCEERR_AO:
108020a203aSopenharmony_ci            codeName << "BUS_MCEERR_AO";
109020a203aSopenharmony_ci            break;
110020a203aSopenharmony_ci        default:
111020a203aSopenharmony_ci            codeName << FormatCommonSignalCodeName(signalCode);
112020a203aSopenharmony_ci            break;
113020a203aSopenharmony_ci    }
114020a203aSopenharmony_ci    return codeName.str();
115020a203aSopenharmony_ci}
116020a203aSopenharmony_ci
117020a203aSopenharmony_cistd::string SignalInfo::FormatSIGILLCodeName(int32_t signalCode)
118020a203aSopenharmony_ci{
119020a203aSopenharmony_ci    std::stringstream codeName;
120020a203aSopenharmony_ci    switch (signalCode) {
121020a203aSopenharmony_ci        case ILL_ILLOPC:
122020a203aSopenharmony_ci            codeName << "ILL_ILLOPC";
123020a203aSopenharmony_ci            break;
124020a203aSopenharmony_ci        case ILL_ILLOPN:
125020a203aSopenharmony_ci            codeName << "ILL_ILLOPN";
126020a203aSopenharmony_ci            break;
127020a203aSopenharmony_ci        case ILL_ILLADR:
128020a203aSopenharmony_ci            codeName << "ILL_ILLADR";
129020a203aSopenharmony_ci            break;
130020a203aSopenharmony_ci        case ILL_ILLTRP:
131020a203aSopenharmony_ci            codeName << "ILL_ILLTRP";
132020a203aSopenharmony_ci            break;
133020a203aSopenharmony_ci        case ILL_PRVOPC:
134020a203aSopenharmony_ci            codeName << "ILL_PRVOPC";
135020a203aSopenharmony_ci            break;
136020a203aSopenharmony_ci        case ILL_PRVREG:
137020a203aSopenharmony_ci            codeName << "ILL_PRVREG";
138020a203aSopenharmony_ci            break;
139020a203aSopenharmony_ci        case ILL_COPROC:
140020a203aSopenharmony_ci            codeName << "ILL_COPROC";
141020a203aSopenharmony_ci            break;
142020a203aSopenharmony_ci        case ILL_BADSTK:
143020a203aSopenharmony_ci            codeName << "ILL_BADSTK";
144020a203aSopenharmony_ci            break;
145020a203aSopenharmony_ci        default:
146020a203aSopenharmony_ci            codeName << FormatCommonSignalCodeName(signalCode);
147020a203aSopenharmony_ci            break;
148020a203aSopenharmony_ci    }
149020a203aSopenharmony_ci    return codeName.str();
150020a203aSopenharmony_ci}
151020a203aSopenharmony_ci
152020a203aSopenharmony_cistd::string SignalInfo::FormatSIGFPECodeName(int32_t signalCode)
153020a203aSopenharmony_ci{
154020a203aSopenharmony_ci    std::stringstream codeName;
155020a203aSopenharmony_ci    switch (signalCode) {
156020a203aSopenharmony_ci        case FPE_INTDIV:
157020a203aSopenharmony_ci            codeName << "FPE_INTDIV";
158020a203aSopenharmony_ci            break;
159020a203aSopenharmony_ci        case FPE_INTOVF:
160020a203aSopenharmony_ci            codeName << "FPE_INTOVF";
161020a203aSopenharmony_ci            break;
162020a203aSopenharmony_ci        case FPE_FLTDIV:
163020a203aSopenharmony_ci            codeName << "FPE_FLTDIV";
164020a203aSopenharmony_ci            break;
165020a203aSopenharmony_ci        case FPE_FLTOVF:
166020a203aSopenharmony_ci            codeName << "FPE_FLTOVF";
167020a203aSopenharmony_ci            break;
168020a203aSopenharmony_ci        case FPE_FLTUND:
169020a203aSopenharmony_ci            codeName << "FPE_FLTUND";
170020a203aSopenharmony_ci            break;
171020a203aSopenharmony_ci        case FPE_FLTRES:
172020a203aSopenharmony_ci            codeName << "FPE_FLTRES";
173020a203aSopenharmony_ci            break;
174020a203aSopenharmony_ci        case FPE_FLTINV:
175020a203aSopenharmony_ci            codeName << "FPE_FLTINV";
176020a203aSopenharmony_ci            break;
177020a203aSopenharmony_ci        case FPE_FLTSUB:
178020a203aSopenharmony_ci            codeName << "FPE_FLTSUB";
179020a203aSopenharmony_ci            break;
180020a203aSopenharmony_ci        default:
181020a203aSopenharmony_ci            codeName << FormatCommonSignalCodeName(signalCode);
182020a203aSopenharmony_ci            break;
183020a203aSopenharmony_ci    }
184020a203aSopenharmony_ci    return codeName.str();
185020a203aSopenharmony_ci}
186020a203aSopenharmony_ci
187020a203aSopenharmony_cistd::string SignalInfo::FormatSIGSEGVCodeName(int32_t signalCode)
188020a203aSopenharmony_ci{
189020a203aSopenharmony_ci    std::stringstream codeName;
190020a203aSopenharmony_ci    switch (signalCode) {
191020a203aSopenharmony_ci        case SEGV_MAPERR:
192020a203aSopenharmony_ci            codeName << "SEGV_MAPERR";
193020a203aSopenharmony_ci            break;
194020a203aSopenharmony_ci        case SEGV_ACCERR:
195020a203aSopenharmony_ci            codeName << "SEGV_ACCERR";
196020a203aSopenharmony_ci            break;
197020a203aSopenharmony_ci        default:
198020a203aSopenharmony_ci            codeName << FormatCommonSignalCodeName(signalCode);
199020a203aSopenharmony_ci            break;
200020a203aSopenharmony_ci    }
201020a203aSopenharmony_ci    return codeName.str();
202020a203aSopenharmony_ci}
203020a203aSopenharmony_ci
204020a203aSopenharmony_cistd::string SignalInfo::FormatSIGTRAPCodeName(int32_t signalCode)
205020a203aSopenharmony_ci{
206020a203aSopenharmony_ci    std::stringstream codeName;
207020a203aSopenharmony_ci    switch (signalCode) {
208020a203aSopenharmony_ci        case TRAP_BRKPT:
209020a203aSopenharmony_ci            codeName << "TRAP_BRKPT";
210020a203aSopenharmony_ci            break;
211020a203aSopenharmony_ci        case TRAP_TRACE:
212020a203aSopenharmony_ci            codeName << "TRAP_TRACE";
213020a203aSopenharmony_ci            break;
214020a203aSopenharmony_ci        case TRAP_BRANCH:
215020a203aSopenharmony_ci            codeName << "TRAP_BRANCH";
216020a203aSopenharmony_ci            break;
217020a203aSopenharmony_ci        case TRAP_HWBKPT:
218020a203aSopenharmony_ci            codeName << "TRAP_HWBKPT";
219020a203aSopenharmony_ci            break;
220020a203aSopenharmony_ci        default:
221020a203aSopenharmony_ci            codeName << FormatCommonSignalCodeName(signalCode);
222020a203aSopenharmony_ci            break;
223020a203aSopenharmony_ci    }
224020a203aSopenharmony_ci    return codeName.str();
225020a203aSopenharmony_ci}
226020a203aSopenharmony_ci
227020a203aSopenharmony_cistd::string SignalInfo::FormatCommonSignalCodeName(int32_t signalCode)
228020a203aSopenharmony_ci{
229020a203aSopenharmony_ci    std::stringstream codeName;
230020a203aSopenharmony_ci    switch (signalCode) {
231020a203aSopenharmony_ci        case SI_USER:
232020a203aSopenharmony_ci            codeName << "SI_USER";
233020a203aSopenharmony_ci            break;
234020a203aSopenharmony_ci        case SI_KERNEL:
235020a203aSopenharmony_ci            codeName << "SI_KERNEL";
236020a203aSopenharmony_ci            break;
237020a203aSopenharmony_ci        case SI_QUEUE:
238020a203aSopenharmony_ci            codeName << "SI_QUEUE";
239020a203aSopenharmony_ci            break;
240020a203aSopenharmony_ci        case SI_TIMER:
241020a203aSopenharmony_ci            codeName << "SI_TIMER";
242020a203aSopenharmony_ci            break;
243020a203aSopenharmony_ci        case SI_MESGQ:
244020a203aSopenharmony_ci            codeName << "SI_MESGQ";
245020a203aSopenharmony_ci            break;
246020a203aSopenharmony_ci        case SI_ASYNCIO:
247020a203aSopenharmony_ci            codeName << "SI_ASYNCIO";
248020a203aSopenharmony_ci            break;
249020a203aSopenharmony_ci        case SI_SIGIO:
250020a203aSopenharmony_ci            codeName << "SI_SIGIO";
251020a203aSopenharmony_ci            break;
252020a203aSopenharmony_ci        case SI_TKILL:
253020a203aSopenharmony_ci            codeName << "SI_TKILL";
254020a203aSopenharmony_ci            break;
255020a203aSopenharmony_ci        default:
256020a203aSopenharmony_ci            codeName << "Unknown Code:" << signalCode;
257020a203aSopenharmony_ci            break;
258020a203aSopenharmony_ci    }
259020a203aSopenharmony_ci    return codeName.str();
260020a203aSopenharmony_ci}
261020a203aSopenharmony_ci
262020a203aSopenharmony_cistd::string SignalInfo::FormatCodeName(int32_t signal, int32_t signalCode)
263020a203aSopenharmony_ci{
264020a203aSopenharmony_ci    switch (signal) {
265020a203aSopenharmony_ci        case SIGILL:
266020a203aSopenharmony_ci            return FormatSIGILLCodeName(signalCode);
267020a203aSopenharmony_ci        case SIGBUS:
268020a203aSopenharmony_ci            return FormatSIGBUSCodeName(signalCode);
269020a203aSopenharmony_ci        case SIGFPE:
270020a203aSopenharmony_ci            return FormatSIGFPECodeName(signalCode);
271020a203aSopenharmony_ci        case SIGSEGV:
272020a203aSopenharmony_ci            return FormatSIGSEGVCodeName(signalCode);
273020a203aSopenharmony_ci        case SIGTRAP:
274020a203aSopenharmony_ci            return FormatSIGTRAPCodeName(signalCode);
275020a203aSopenharmony_ci        default:
276020a203aSopenharmony_ci            break;
277020a203aSopenharmony_ci    }
278020a203aSopenharmony_ci    return FormatCommonSignalCodeName(signalCode);
279020a203aSopenharmony_ci}
280020a203aSopenharmony_ci}  // namespace HiviewDFX
281020a203aSopenharmony_ci}  // namespace OHOS
282