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 "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