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