Home | History | Annotate | Download | only in runtime
      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