1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "runtime_common.h" 18 19 #include <signal.h> 20 21 #include <cinttypes> 22 #include <iostream> 23 #include <sstream> 24 #include <string> 25 26 #include "android-base/stringprintf.h" 27 28 #include "base/logging.h" 29 #include "base/macros.h" 30 #include "base/mutex.h" 31 #include "native_stack_dump.h" 32 #include "thread-inl.h" 33 #include "thread_list.h" 34 35 namespace art { 36 37 using android::base::StringPrintf; 38 39 static constexpr bool kUseSigRTTimeout = true; 40 static constexpr bool kDumpNativeStackOnTimeout = true; 41 42 const char* GetSignalName(int signal_number) { 43 switch (signal_number) { 44 case SIGABRT: return "SIGABRT"; 45 case SIGBUS: return "SIGBUS"; 46 case SIGFPE: return "SIGFPE"; 47 case SIGILL: return "SIGILL"; 48 case SIGPIPE: return "SIGPIPE"; 49 case SIGSEGV: return "SIGSEGV"; 50 #if defined(SIGSTKFLT) 51 case SIGSTKFLT: return "SIGSTKFLT"; 52 #endif 53 case SIGTRAP: return "SIGTRAP"; 54 } 55 return "??"; 56 } 57 58 const char* GetSignalCodeName(int signal_number, int signal_code) { 59 // Try the signal-specific codes... 60 switch (signal_number) { 61 case SIGILL: 62 switch (signal_code) { 63 case ILL_ILLOPC: return "ILL_ILLOPC"; 64 case ILL_ILLOPN: return "ILL_ILLOPN"; 65 case ILL_ILLADR: return "ILL_ILLADR"; 66 case ILL_ILLTRP: return "ILL_ILLTRP"; 67 case ILL_PRVOPC: return "ILL_PRVOPC"; 68 case ILL_PRVREG: return "ILL_PRVREG"; 69 case ILL_COPROC: return "ILL_COPROC"; 70 case ILL_BADSTK: return "ILL_BADSTK"; 71 } 72 break; 73 case SIGBUS: 74 switch (signal_code) { 75 case BUS_ADRALN: return "BUS_ADRALN"; 76 case BUS_ADRERR: return "BUS_ADRERR"; 77 case BUS_OBJERR: return "BUS_OBJERR"; 78 } 79 break; 80 case SIGFPE: 81 switch (signal_code) { 82 case FPE_INTDIV: return "FPE_INTDIV"; 83 case FPE_INTOVF: return "FPE_INTOVF"; 84 case FPE_FLTDIV: return "FPE_FLTDIV"; 85 case FPE_FLTOVF: return "FPE_FLTOVF"; 86 case FPE_FLTUND: return "FPE_FLTUND"; 87 case FPE_FLTRES: return "FPE_FLTRES"; 88 case FPE_FLTINV: return "FPE_FLTINV"; 89 case FPE_FLTSUB: return "FPE_FLTSUB"; 90 } 91 break; 92 case SIGSEGV: 93 switch (signal_code) { 94 case SEGV_MAPERR: return "SEGV_MAPERR"; 95 case SEGV_ACCERR: return "SEGV_ACCERR"; 96 #if defined(SEGV_BNDERR) 97 case SEGV_BNDERR: return "SEGV_BNDERR"; 98 #endif 99 } 100 break; 101 case SIGTRAP: 102 switch (signal_code) { 103 case TRAP_BRKPT: return "TRAP_BRKPT"; 104 case TRAP_TRACE: return "TRAP_TRACE"; 105 } 106 break; 107 } 108 // Then the other codes... 109 switch (signal_code) { 110 case SI_USER: return "SI_USER"; 111 #if defined(SI_KERNEL) 112 case SI_KERNEL: return "SI_KERNEL"; 113 #endif 114 case SI_QUEUE: return "SI_QUEUE"; 115 case SI_TIMER: return "SI_TIMER"; 116 case SI_MESGQ: return "SI_MESGQ"; 117 case SI_ASYNCIO: return "SI_ASYNCIO"; 118 #if defined(SI_SIGIO) 119 case SI_SIGIO: return "SI_SIGIO"; 120 #endif 121 #if defined(SI_TKILL) 122 case SI_TKILL: return "SI_TKILL"; 123 #endif 124 } 125 // Then give up... 126 return "?"; 127 } 128 129 struct UContext { 130 explicit UContext(void* raw_context) 131 : context(reinterpret_cast<ucontext_t*>(raw_context)->uc_mcontext) {} 132 133 void Dump(std::ostream& os) const; 134 135 void DumpRegister32(std::ostream& os, const char* name, uint32_t value) const; 136 void DumpRegister64(std::ostream& os, const char* name, uint64_t value) const; 137 138 void DumpX86Flags(std::ostream& os, uint32_t flags) const; 139 // Print some of the information from the status register (CPSR on ARMv7, PSTATE on ARMv8). 140 template <typename RegisterType> 141 void DumpArmStatusRegister(std::ostream& os, RegisterType status_register) const; 142 143 mcontext_t& context; 144 }; 145 146 void UContext::Dump(std::ostream& os) const { 147 #if defined(__APPLE__) && defined(__i386__) 148 DumpRegister32(os, "eax", context->__ss.__eax); 149 DumpRegister32(os, "ebx", context->__ss.__ebx); 150 DumpRegister32(os, "ecx", context->__ss.__ecx); 151 DumpRegister32(os, "edx", context->__ss.__edx); 152 os << '\n'; 153 154 DumpRegister32(os, "edi", context->__ss.__edi); 155 DumpRegister32(os, "esi", context->__ss.__esi); 156 DumpRegister32(os, "ebp", context->__ss.__ebp); 157 DumpRegister32(os, "esp", context->__ss.__esp); 158 os << '\n'; 159 160 DumpRegister32(os, "eip", context->__ss.__eip); 161 os << " "; 162 DumpRegister32(os, "eflags", context->__ss.__eflags); 163 DumpX86Flags(os, context->__ss.__eflags); 164 os << '\n'; 165 166 DumpRegister32(os, "cs", context->__ss.__cs); 167 DumpRegister32(os, "ds", context->__ss.__ds); 168 DumpRegister32(os, "es", context->__ss.__es); 169 DumpRegister32(os, "fs", context->__ss.__fs); 170 os << '\n'; 171 DumpRegister32(os, "gs", context->__ss.__gs); 172 DumpRegister32(os, "ss", context->__ss.__ss); 173 #elif defined(__linux__) && defined(__i386__) 174 DumpRegister32(os, "eax", context.gregs[REG_EAX]); 175 DumpRegister32(os, "ebx", context.gregs[REG_EBX]); 176 DumpRegister32(os, "ecx", context.gregs[REG_ECX]); 177 DumpRegister32(os, "edx", context.gregs[REG_EDX]); 178 os << '\n'; 179 180 DumpRegister32(os, "edi", context.gregs[REG_EDI]); 181 DumpRegister32(os, "esi", context.gregs[REG_ESI]); 182 DumpRegister32(os, "ebp", context.gregs[REG_EBP]); 183 DumpRegister32(os, "esp", context.gregs[REG_ESP]); 184 os << '\n'; 185 186 DumpRegister32(os, "eip", context.gregs[REG_EIP]); 187 os << " "; 188 DumpRegister32(os, "eflags", context.gregs[REG_EFL]); 189 DumpX86Flags(os, context.gregs[REG_EFL]); 190 os << '\n'; 191 192 DumpRegister32(os, "cs", context.gregs[REG_CS]); 193 DumpRegister32(os, "ds", context.gregs[REG_DS]); 194 DumpRegister32(os, "es", context.gregs[REG_ES]); 195 DumpRegister32(os, "fs", context.gregs[REG_FS]); 196 os << '\n'; 197 DumpRegister32(os, "gs", context.gregs[REG_GS]); 198 DumpRegister32(os, "ss", context.gregs[REG_SS]); 199 #elif defined(__linux__) && defined(__x86_64__) 200 DumpRegister64(os, "rax", context.gregs[REG_RAX]); 201 DumpRegister64(os, "rbx", context.gregs[REG_RBX]); 202 DumpRegister64(os, "rcx", context.gregs[REG_RCX]); 203 DumpRegister64(os, "rdx", context.gregs[REG_RDX]); 204 os << '\n'; 205 206 DumpRegister64(os, "rdi", context.gregs[REG_RDI]); 207 DumpRegister64(os, "rsi", context.gregs[REG_RSI]); 208 DumpRegister64(os, "rbp", context.gregs[REG_RBP]); 209 DumpRegister64(os, "rsp", context.gregs[REG_RSP]); 210 os << '\n'; 211 212 DumpRegister64(os, "r8 ", context.gregs[REG_R8]); 213 DumpRegister64(os, "r9 ", context.gregs[REG_R9]); 214 DumpRegister64(os, "r10", context.gregs[REG_R10]); 215 DumpRegister64(os, "r11", context.gregs[REG_R11]); 216 os << '\n'; 217 218 DumpRegister64(os, "r12", context.gregs[REG_R12]); 219 DumpRegister64(os, "r13", context.gregs[REG_R13]); 220 DumpRegister64(os, "r14", context.gregs[REG_R14]); 221 DumpRegister64(os, "r15", context.gregs[REG_R15]); 222 os << '\n'; 223 224 DumpRegister64(os, "rip", context.gregs[REG_RIP]); 225 os << " "; 226 DumpRegister32(os, "eflags", context.gregs[REG_EFL]); 227 DumpX86Flags(os, context.gregs[REG_EFL]); 228 os << '\n'; 229 230 DumpRegister32(os, "cs", (context.gregs[REG_CSGSFS]) & 0x0FFFF); 231 DumpRegister32(os, "gs", (context.gregs[REG_CSGSFS] >> 16) & 0x0FFFF); 232 DumpRegister32(os, "fs", (context.gregs[REG_CSGSFS] >> 32) & 0x0FFFF); 233 os << '\n'; 234 #elif defined(__linux__) && defined(__arm__) 235 DumpRegister32(os, "r0", context.arm_r0); 236 DumpRegister32(os, "r1", context.arm_r1); 237 DumpRegister32(os, "r2", context.arm_r2); 238 DumpRegister32(os, "r3", context.arm_r3); 239 os << '\n'; 240 241 DumpRegister32(os, "r4", context.arm_r4); 242 DumpRegister32(os, "r5", context.arm_r5); 243 DumpRegister32(os, "r6", context.arm_r6); 244 DumpRegister32(os, "r7", context.arm_r7); 245 os << '\n'; 246 247 DumpRegister32(os, "r8", context.arm_r8); 248 DumpRegister32(os, "r9", context.arm_r9); 249 DumpRegister32(os, "r10", context.arm_r10); 250 DumpRegister32(os, "fp", context.arm_fp); 251 os << '\n'; 252 253 DumpRegister32(os, "ip", context.arm_ip); 254 DumpRegister32(os, "sp", context.arm_sp); 255 DumpRegister32(os, "lr", context.arm_lr); 256 DumpRegister32(os, "pc", context.arm_pc); 257 os << '\n'; 258 259 DumpRegister32(os, "cpsr", context.arm_cpsr); 260 DumpArmStatusRegister(os, context.arm_cpsr); 261 os << '\n'; 262 #elif defined(__linux__) && defined(__aarch64__) 263 for (size_t i = 0; i <= 30; ++i) { 264 std::string reg_name = "x" + std::to_string(i); 265 DumpRegister64(os, reg_name.c_str(), context.regs[i]); 266 if (i % 4 == 3) { 267 os << '\n'; 268 } 269 } 270 os << '\n'; 271 272 DumpRegister64(os, "sp", context.sp); 273 DumpRegister64(os, "pc", context.pc); 274 os << '\n'; 275 276 DumpRegister64(os, "pstate", context.pstate); 277 DumpArmStatusRegister(os, context.pstate); 278 os << '\n'; 279 #else 280 // TODO: Add support for MIPS32 and MIPS64. 281 os << "Unknown architecture/word size/OS in ucontext dump"; 282 #endif 283 } 284 285 void UContext::DumpRegister32(std::ostream& os, const char* name, uint32_t value) const { 286 os << StringPrintf(" %6s: 0x%08x", name, value); 287 } 288 289 void UContext::DumpRegister64(std::ostream& os, const char* name, uint64_t value) const { 290 os << StringPrintf(" %6s: 0x%016" PRIx64, name, value); 291 } 292 293 void UContext::DumpX86Flags(std::ostream& os, uint32_t flags) const { 294 os << " ["; 295 if ((flags & (1 << 0)) != 0) { 296 os << " CF"; 297 } 298 if ((flags & (1 << 2)) != 0) { 299 os << " PF"; 300 } 301 if ((flags & (1 << 4)) != 0) { 302 os << " AF"; 303 } 304 if ((flags & (1 << 6)) != 0) { 305 os << " ZF"; 306 } 307 if ((flags & (1 << 7)) != 0) { 308 os << " SF"; 309 } 310 if ((flags & (1 << 8)) != 0) { 311 os << " TF"; 312 } 313 if ((flags & (1 << 9)) != 0) { 314 os << " IF"; 315 } 316 if ((flags & (1 << 10)) != 0) { 317 os << " DF"; 318 } 319 if ((flags & (1 << 11)) != 0) { 320 os << " OF"; 321 } 322 os << " ]"; 323 } 324 325 template <typename RegisterType> 326 void UContext::DumpArmStatusRegister(std::ostream& os, RegisterType status_register) const { 327 // Condition flags. 328 constexpr RegisterType kFlagV = 1U << 28; 329 constexpr RegisterType kFlagC = 1U << 29; 330 constexpr RegisterType kFlagZ = 1U << 30; 331 constexpr RegisterType kFlagN = 1U << 31; 332 333 os << " ["; 334 if ((status_register & kFlagN) != 0) { 335 os << " N"; 336 } 337 if ((status_register & kFlagZ) != 0) { 338 os << " Z"; 339 } 340 if ((status_register & kFlagC) != 0) { 341 os << " C"; 342 } 343 if ((status_register & kFlagV) != 0) { 344 os << " V"; 345 } 346 os << " ]"; 347 } 348 349 int GetTimeoutSignal() { 350 #if defined(__APPLE__) 351 // Mac does not support realtime signals. 352 UNUSED(kUseSigRTTimeout); 353 return -1; 354 #else 355 return kUseSigRTTimeout ? (SIGRTMIN + 2) : -1; 356 #endif 357 } 358 359 static bool IsTimeoutSignal(int signal_number) { 360 return signal_number == GetTimeoutSignal(); 361 } 362 363 #if defined(__APPLE__) 364 // On macOS, clang complains about art::HandleUnexpectedSignalCommon's 365 // stack frame size being too large; disable that warning locally. 366 #pragma GCC diagnostic push 367 #pragma GCC diagnostic ignored "-Wframe-larger-than=" 368 #endif 369 370 void HandleUnexpectedSignalCommon(int signal_number, 371 siginfo_t* info, 372 void* raw_context, 373 bool running_on_linux) { 374 bool handle_timeout_signal = running_on_linux; 375 bool dump_on_stderr = running_on_linux; 376 377 static bool handling_unexpected_signal = false; 378 if (handling_unexpected_signal) { 379 LogHelper::LogLineLowStack(__FILE__, 380 __LINE__, 381 ::android::base::FATAL_WITHOUT_ABORT, 382 "HandleUnexpectedSignal reentered\n"); 383 if (handle_timeout_signal) { 384 if (IsTimeoutSignal(signal_number)) { 385 // Ignore a recursive timeout. 386 return; 387 } 388 } 389 _exit(1); 390 } 391 handling_unexpected_signal = true; 392 393 gAborting++; // set before taking any locks 394 MutexLock mu(Thread::Current(), *Locks::unexpected_signal_lock_); 395 396 bool has_address = (signal_number == SIGILL || signal_number == SIGBUS || 397 signal_number == SIGFPE || signal_number == SIGSEGV); 398 399 OsInfo os_info; 400 const char* cmd_line = GetCmdLine(); 401 if (cmd_line == nullptr) { 402 cmd_line = "<unset>"; // Because no-one called InitLogging. 403 } 404 pid_t tid = GetTid(); 405 std::string thread_name(GetThreadName(tid)); 406 UContext thread_context(raw_context); 407 Backtrace thread_backtrace(raw_context); 408 409 std::ostringstream stream; 410 stream << "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n" 411 << StringPrintf("Fatal signal %d (%s), code %d (%s)", 412 signal_number, 413 GetSignalName(signal_number), 414 info->si_code, 415 GetSignalCodeName(signal_number, info->si_code)) 416 << (has_address ? StringPrintf(" fault addr %p", info->si_addr) : "") << '\n' 417 << "OS: " << Dumpable<OsInfo>(os_info) << '\n' 418 << "Cmdline: " << cmd_line << '\n' 419 << "Thread: " << tid << " \"" << thread_name << "\"" << '\n' 420 << "Registers:\n" << Dumpable<UContext>(thread_context) << '\n' 421 << "Backtrace:\n" << Dumpable<Backtrace>(thread_backtrace) << '\n'; 422 if (dump_on_stderr) { 423 // Note: We are using cerr directly instead of LOG macros to ensure even just partial output 424 // makes it out. That means we lose the "dalvikvm..." prefix, but that is acceptable 425 // considering this is an abort situation. 426 std::cerr << stream.str() << std::flush; 427 } else { 428 LOG(FATAL_WITHOUT_ABORT) << stream.str() << std::flush; 429 } 430 if (kIsDebugBuild && signal_number == SIGSEGV) { 431 PrintFileToLog("/proc/self/maps", LogSeverity::FATAL_WITHOUT_ABORT); 432 } 433 434 Runtime* runtime = Runtime::Current(); 435 if (runtime != nullptr) { 436 if (handle_timeout_signal && IsTimeoutSignal(signal_number)) { 437 // Special timeout signal. Try to dump all threads. 438 // Note: Do not use DumpForSigQuit, as that might disable native unwind, but the native parts 439 // are of value here. 440 runtime->GetThreadList()->Dump(std::cerr, kDumpNativeStackOnTimeout); 441 std::cerr << std::endl; 442 } 443 444 if (dump_on_stderr) { 445 std::cerr << "Fault message: " << runtime->GetFaultMessage() << std::endl; 446 } else { 447 LOG(FATAL_WITHOUT_ABORT) << "Fault message: " << runtime->GetFaultMessage(); 448 } 449 } 450 } 451 452 #if defined(__APPLE__) 453 #pragma GCC diagnostic pop 454 #endif 455 456 void InitPlatformSignalHandlersCommon(void (*newact)(int, siginfo_t*, void*), 457 struct sigaction* oldact, 458 bool handle_timeout_signal) { 459 struct sigaction action; 460 memset(&action, 0, sizeof(action)); 461 sigemptyset(&action.sa_mask); 462 action.sa_sigaction = newact; 463 // Use the three-argument sa_sigaction handler. 464 action.sa_flags |= SA_SIGINFO; 465 // Use the alternate signal stack so we can catch stack overflows. 466 action.sa_flags |= SA_ONSTACK; 467 468 int rc = 0; 469 rc += sigaction(SIGABRT, &action, oldact); 470 rc += sigaction(SIGBUS, &action, oldact); 471 rc += sigaction(SIGFPE, &action, oldact); 472 rc += sigaction(SIGILL, &action, oldact); 473 rc += sigaction(SIGPIPE, &action, oldact); 474 rc += sigaction(SIGSEGV, &action, oldact); 475 #if defined(SIGSTKFLT) 476 rc += sigaction(SIGSTKFLT, &action, oldact); 477 #endif 478 rc += sigaction(SIGTRAP, &action, oldact); 479 // Special dump-all timeout. 480 if (handle_timeout_signal && GetTimeoutSignal() != -1) { 481 rc += sigaction(GetTimeoutSignal(), &action, oldact); 482 } 483 CHECK_EQ(rc, 0); 484 } 485 486 } // namespace art 487