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 22namespace OHOS { 23namespace HiviewDFX { 24void 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 38bool 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 47bool SignalInfo::IsSignalAddrAvaliable(int32_t signal) 48{ 49 return ((signal == SIGABRT) || (signal == SIGBUS) || (signal == SIGILL) 50 || (signal == SIGSEGV) || (signal == SIGTRAP)); 51} 52 53bool SignalInfo::IsSignalPidAvaliable(int32_t sigCode) 54{ 55 switch (sigCode) { 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 67std::string SignalInfo::FormatSignalName(int32_t signal) 68{ 69 switch (signal) { 70 case SIGABRT: 71 return "SIGABRT"; 72 case SIGALRM: 73 return "SIGALRM"; 74 case SIGBUS: 75 return "SIGBUS"; 76 case SIGFPE: 77 return "SIGFPE"; 78 case SIGILL: 79 return "SIGILL"; 80 case SIGSEGV: 81 return "SIGSEGV"; 82 case SIGSYS: 83 return "SIGSYS"; 84 case SIGTRAP: 85 return "SIGTRAP"; 86 default: 87 return "Uncare Signal"; 88 } 89} 90 91std::string SignalInfo::FormatSIGBUSCodeName(int32_t signalCode) 92{ 93 std::stringstream codeName; 94 switch (signalCode) { 95 case BUS_ADRALN: 96 codeName << "BUS_ADRALN"; 97 break; 98 case BUS_ADRERR: 99 codeName << "BUS_ADRERR"; 100 break; 101 case BUS_OBJERR: 102 codeName << "BUS_OBJERR"; 103 break; 104 case BUS_MCEERR_AR: 105 codeName << "BUS_MCEERR_AR"; 106 break; 107 case BUS_MCEERR_AO: 108 codeName << "BUS_MCEERR_AO"; 109 break; 110 default: 111 codeName << FormatCommonSignalCodeName(signalCode); 112 break; 113 } 114 return codeName.str(); 115} 116 117std::string SignalInfo::FormatSIGILLCodeName(int32_t signalCode) 118{ 119 std::stringstream codeName; 120 switch (signalCode) { 121 case ILL_ILLOPC: 122 codeName << "ILL_ILLOPC"; 123 break; 124 case ILL_ILLOPN: 125 codeName << "ILL_ILLOPN"; 126 break; 127 case ILL_ILLADR: 128 codeName << "ILL_ILLADR"; 129 break; 130 case ILL_ILLTRP: 131 codeName << "ILL_ILLTRP"; 132 break; 133 case ILL_PRVOPC: 134 codeName << "ILL_PRVOPC"; 135 break; 136 case ILL_PRVREG: 137 codeName << "ILL_PRVREG"; 138 break; 139 case ILL_COPROC: 140 codeName << "ILL_COPROC"; 141 break; 142 case ILL_BADSTK: 143 codeName << "ILL_BADSTK"; 144 break; 145 default: 146 codeName << FormatCommonSignalCodeName(signalCode); 147 break; 148 } 149 return codeName.str(); 150} 151 152std::string SignalInfo::FormatSIGFPECodeName(int32_t signalCode) 153{ 154 std::stringstream codeName; 155 switch (signalCode) { 156 case FPE_INTDIV: 157 codeName << "FPE_INTDIV"; 158 break; 159 case FPE_INTOVF: 160 codeName << "FPE_INTOVF"; 161 break; 162 case FPE_FLTDIV: 163 codeName << "FPE_FLTDIV"; 164 break; 165 case FPE_FLTOVF: 166 codeName << "FPE_FLTOVF"; 167 break; 168 case FPE_FLTUND: 169 codeName << "FPE_FLTUND"; 170 break; 171 case FPE_FLTRES: 172 codeName << "FPE_FLTRES"; 173 break; 174 case FPE_FLTINV: 175 codeName << "FPE_FLTINV"; 176 break; 177 case FPE_FLTSUB: 178 codeName << "FPE_FLTSUB"; 179 break; 180 default: 181 codeName << FormatCommonSignalCodeName(signalCode); 182 break; 183 } 184 return codeName.str(); 185} 186 187std::string SignalInfo::FormatSIGSEGVCodeName(int32_t signalCode) 188{ 189 std::stringstream codeName; 190 switch (signalCode) { 191 case SEGV_MAPERR: 192 codeName << "SEGV_MAPERR"; 193 break; 194 case SEGV_ACCERR: 195 codeName << "SEGV_ACCERR"; 196 break; 197 default: 198 codeName << FormatCommonSignalCodeName(signalCode); 199 break; 200 } 201 return codeName.str(); 202} 203 204std::string SignalInfo::FormatSIGTRAPCodeName(int32_t signalCode) 205{ 206 std::stringstream codeName; 207 switch (signalCode) { 208 case TRAP_BRKPT: 209 codeName << "TRAP_BRKPT"; 210 break; 211 case TRAP_TRACE: 212 codeName << "TRAP_TRACE"; 213 break; 214 case TRAP_BRANCH: 215 codeName << "TRAP_BRANCH"; 216 break; 217 case TRAP_HWBKPT: 218 codeName << "TRAP_HWBKPT"; 219 break; 220 default: 221 codeName << FormatCommonSignalCodeName(signalCode); 222 break; 223 } 224 return codeName.str(); 225} 226 227std::string SignalInfo::FormatCommonSignalCodeName(int32_t signalCode) 228{ 229 std::stringstream codeName; 230 switch (signalCode) { 231 case SI_USER: 232 codeName << "SI_USER"; 233 break; 234 case SI_KERNEL: 235 codeName << "SI_KERNEL"; 236 break; 237 case SI_QUEUE: 238 codeName << "SI_QUEUE"; 239 break; 240 case SI_TIMER: 241 codeName << "SI_TIMER"; 242 break; 243 case SI_MESGQ: 244 codeName << "SI_MESGQ"; 245 break; 246 case SI_ASYNCIO: 247 codeName << "SI_ASYNCIO"; 248 break; 249 case SI_SIGIO: 250 codeName << "SI_SIGIO"; 251 break; 252 case SI_TKILL: 253 codeName << "SI_TKILL"; 254 break; 255 default: 256 codeName << "Unknown Code:" << signalCode; 257 break; 258 } 259 return codeName.str(); 260} 261 262std::string SignalInfo::FormatCodeName(int32_t signal, int32_t signalCode) 263{ 264 switch (signal) { 265 case SIGILL: 266 return FormatSIGILLCodeName(signalCode); 267 case SIGBUS: 268 return FormatSIGBUSCodeName(signalCode); 269 case SIGFPE: 270 return FormatSIGFPECodeName(signalCode); 271 case SIGSEGV: 272 return FormatSIGSEGVCodeName(signalCode); 273 case SIGTRAP: 274 return FormatSIGTRAPCodeName(signalCode); 275 default: 276 break; 277 } 278 return FormatCommonSignalCodeName(signalCode); 279} 280} // namespace HiviewDFX 281} // namespace OHOS 282