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