Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2008 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 "fault_handler.h"
     18 
     19 #include <setjmp.h>
     20 #include <string.h>
     21 #include <sys/mman.h>
     22 #include <sys/ucontext.h>
     23 
     24 #include "art_method-inl.h"
     25 #include "base/logging.h"  // For VLOG
     26 #include "base/safe_copy.h"
     27 #include "base/stl_util.h"
     28 #include "dex/dex_file_types.h"
     29 #include "mirror/class.h"
     30 #include "mirror/object_reference.h"
     31 #include "oat_quick_method_header.h"
     32 #include "sigchain.h"
     33 #include "thread-current-inl.h"
     34 #include "verify_object-inl.h"
     35 
     36 namespace art {
     37 // Static fault manger object accessed by signal handler.
     38 FaultManager fault_manager;
     39 
     40 // This needs to be NO_INLINE since some debuggers do not read the inline-info to set a breakpoint
     41 // if it isn't.
     42 extern "C" NO_INLINE __attribute__((visibility("default"))) void art_sigsegv_fault() {
     43   // Set a breakpoint here to be informed when a SIGSEGV is unhandled by ART.
     44   VLOG(signals)<< "Caught unknown SIGSEGV in ART fault handler - chaining to next handler.";
     45 }
     46 
     47 // Signal handler called on SIGSEGV.
     48 static bool art_fault_handler(int sig, siginfo_t* info, void* context) {
     49   return fault_manager.HandleFault(sig, info, context);
     50 }
     51 
     52 #if defined(__linux__)
     53 
     54 // Change to verify the safe implementations against the original ones.
     55 constexpr bool kVerifySafeImpls = false;
     56 
     57 // Provide implementations of ArtMethod::GetDeclaringClass and VerifyClassClass that use SafeCopy
     58 // to safely dereference pointers which are potentially garbage.
     59 // Only available on Linux due to availability of SafeCopy.
     60 
     61 static mirror::Class* SafeGetDeclaringClass(ArtMethod* method)
     62     REQUIRES_SHARED(Locks::mutator_lock_) {
     63   char* method_declaring_class =
     64       reinterpret_cast<char*>(method) + ArtMethod::DeclaringClassOffset().SizeValue();
     65 
     66   // ArtMethod::declaring_class_ is a GcRoot<mirror::Class>.
     67   // Read it out into as a CompressedReference directly for simplicity's sake.
     68   mirror::CompressedReference<mirror::Class> cls;
     69   ssize_t rc = SafeCopy(&cls, method_declaring_class, sizeof(cls));
     70   CHECK_NE(-1, rc);
     71 
     72   if (kVerifySafeImpls) {
     73     mirror::Class* actual_class = method->GetDeclaringClassUnchecked<kWithoutReadBarrier>();
     74     CHECK_EQ(actual_class, cls.AsMirrorPtr());
     75   }
     76 
     77   if (rc != sizeof(cls)) {
     78     return nullptr;
     79   }
     80 
     81   return cls.AsMirrorPtr();
     82 }
     83 
     84 static mirror::Class* SafeGetClass(mirror::Object* obj) REQUIRES_SHARED(Locks::mutator_lock_) {
     85   char* obj_cls = reinterpret_cast<char*>(obj) + mirror::Object::ClassOffset().SizeValue();
     86 
     87   mirror::HeapReference<mirror::Class> cls;
     88   ssize_t rc = SafeCopy(&cls, obj_cls, sizeof(cls));
     89   CHECK_NE(-1, rc);
     90 
     91   if (kVerifySafeImpls) {
     92     mirror::Class* actual_class = obj->GetClass<kVerifyNone>();
     93     CHECK_EQ(actual_class, cls.AsMirrorPtr());
     94   }
     95 
     96   if (rc != sizeof(cls)) {
     97     return nullptr;
     98   }
     99 
    100   return cls.AsMirrorPtr();
    101 }
    102 
    103 static bool SafeVerifyClassClass(mirror::Class* cls) REQUIRES_SHARED(Locks::mutator_lock_) {
    104   mirror::Class* c_c = SafeGetClass(cls);
    105   bool result = c_c != nullptr && c_c == SafeGetClass(c_c);
    106 
    107   if (kVerifySafeImpls) {
    108     CHECK_EQ(VerifyClassClass(cls), result);
    109   }
    110 
    111   return result;
    112 }
    113 
    114 #else
    115 
    116 static mirror::Class* SafeGetDeclaringClass(ArtMethod* method_obj)
    117     REQUIRES_SHARED(Locks::mutator_lock_) {
    118   return method_obj->GetDeclaringClassUnchecked<kWithoutReadBarrier>();
    119 }
    120 
    121 static bool SafeVerifyClassClass(mirror::Class* cls) REQUIRES_SHARED(Locks::mutator_lock_) {
    122   return VerifyClassClass(cls);
    123 }
    124 #endif
    125 
    126 
    127 FaultManager::FaultManager() : initialized_(false) {
    128   sigaction(SIGSEGV, nullptr, &oldaction_);
    129 }
    130 
    131 FaultManager::~FaultManager() {
    132 }
    133 
    134 void FaultManager::Init() {
    135   CHECK(!initialized_);
    136   sigset_t mask;
    137   sigfillset(&mask);
    138   sigdelset(&mask, SIGABRT);
    139   sigdelset(&mask, SIGBUS);
    140   sigdelset(&mask, SIGFPE);
    141   sigdelset(&mask, SIGILL);
    142   sigdelset(&mask, SIGSEGV);
    143 
    144   SigchainAction sa = {
    145     .sc_sigaction = art_fault_handler,
    146     .sc_mask = mask,
    147     .sc_flags = 0UL,
    148   };
    149 
    150   AddSpecialSignalHandlerFn(SIGSEGV, &sa);
    151   initialized_ = true;
    152 }
    153 
    154 void FaultManager::Release() {
    155   if (initialized_) {
    156     RemoveSpecialSignalHandlerFn(SIGSEGV, art_fault_handler);
    157     initialized_ = false;
    158   }
    159 }
    160 
    161 void FaultManager::Shutdown() {
    162   if (initialized_) {
    163     Release();
    164 
    165     // Free all handlers.
    166     STLDeleteElements(&generated_code_handlers_);
    167     STLDeleteElements(&other_handlers_);
    168   }
    169 }
    170 
    171 bool FaultManager::HandleFaultByOtherHandlers(int sig, siginfo_t* info, void* context) {
    172   if (other_handlers_.empty()) {
    173     return false;
    174   }
    175 
    176   Thread* self = Thread::Current();
    177 
    178   DCHECK(self != nullptr);
    179   DCHECK(Runtime::Current() != nullptr);
    180   DCHECK(Runtime::Current()->IsStarted());
    181   for (const auto& handler : other_handlers_) {
    182     if (handler->Action(sig, info, context)) {
    183       return true;
    184     }
    185   }
    186   return false;
    187 }
    188 
    189 static const char* SignalCodeName(int sig, int code) {
    190   if (sig != SIGSEGV) {
    191     return "UNKNOWN";
    192   } else {
    193     switch (code) {
    194       case SEGV_MAPERR: return "SEGV_MAPERR";
    195       case SEGV_ACCERR: return "SEGV_ACCERR";
    196       default:          return "UNKNOWN";
    197     }
    198   }
    199 }
    200 static std::ostream& PrintSignalInfo(std::ostream& os, siginfo_t* info) {
    201   os << "  si_signo: " << info->si_signo << " (" << strsignal(info->si_signo) << ")\n"
    202      << "  si_code: " << info->si_code
    203      << " (" << SignalCodeName(info->si_signo, info->si_code) << ")";
    204   if (info->si_signo == SIGSEGV) {
    205     os << "\n" << "  si_addr: " << info->si_addr;
    206   }
    207   return os;
    208 }
    209 
    210 bool FaultManager::HandleFault(int sig, siginfo_t* info, void* context) {
    211   if (VLOG_IS_ON(signals)) {
    212     PrintSignalInfo(VLOG_STREAM(signals) << "Handling fault:" << "\n", info);
    213   }
    214 
    215 #ifdef TEST_NESTED_SIGNAL
    216   // Simulate a crash in a handler.
    217   raise(SIGSEGV);
    218 #endif
    219 
    220   if (IsInGeneratedCode(info, context, true)) {
    221     VLOG(signals) << "in generated code, looking for handler";
    222     for (const auto& handler : generated_code_handlers_) {
    223       VLOG(signals) << "invoking Action on handler " << handler;
    224       if (handler->Action(sig, info, context)) {
    225         // We have handled a signal so it's time to return from the
    226         // signal handler to the appropriate place.
    227         return true;
    228       }
    229     }
    230   }
    231 
    232   // We hit a signal we didn't handle.  This might be something for which
    233   // we can give more information about so call all registered handlers to
    234   // see if it is.
    235   if (HandleFaultByOtherHandlers(sig, info, context)) {
    236     return true;
    237   }
    238 
    239   // Set a breakpoint in this function to catch unhandled signals.
    240   art_sigsegv_fault();
    241   return false;
    242 }
    243 
    244 void FaultManager::AddHandler(FaultHandler* handler, bool generated_code) {
    245   DCHECK(initialized_);
    246   if (generated_code) {
    247     generated_code_handlers_.push_back(handler);
    248   } else {
    249     other_handlers_.push_back(handler);
    250   }
    251 }
    252 
    253 void FaultManager::RemoveHandler(FaultHandler* handler) {
    254   auto it = std::find(generated_code_handlers_.begin(), generated_code_handlers_.end(), handler);
    255   if (it != generated_code_handlers_.end()) {
    256     generated_code_handlers_.erase(it);
    257     return;
    258   }
    259   auto it2 = std::find(other_handlers_.begin(), other_handlers_.end(), handler);
    260   if (it2 != other_handlers_.end()) {
    261     other_handlers_.erase(it2);
    262     return;
    263   }
    264   LOG(FATAL) << "Attempted to remove non existent handler " << handler;
    265 }
    266 
    267 // This function is called within the signal handler.  It checks that
    268 // the mutator_lock is held (shared).  No annotalysis is done.
    269 bool FaultManager::IsInGeneratedCode(siginfo_t* siginfo, void* context, bool check_dex_pc) {
    270   // We can only be running Java code in the current thread if it
    271   // is in Runnable state.
    272   VLOG(signals) << "Checking for generated code";
    273   Thread* thread = Thread::Current();
    274   if (thread == nullptr) {
    275     VLOG(signals) << "no current thread";
    276     return false;
    277   }
    278 
    279   ThreadState state = thread->GetState();
    280   if (state != kRunnable) {
    281     VLOG(signals) << "not runnable";
    282     return false;
    283   }
    284 
    285   // Current thread is runnable.
    286   // Make sure it has the mutator lock.
    287   if (!Locks::mutator_lock_->IsSharedHeld(thread)) {
    288     VLOG(signals) << "no lock";
    289     return false;
    290   }
    291 
    292   ArtMethod* method_obj = nullptr;
    293   uintptr_t return_pc = 0;
    294   uintptr_t sp = 0;
    295 
    296   // Get the architecture specific method address and return address.  These
    297   // are in architecture specific files in arch/<arch>/fault_handler_<arch>.
    298   GetMethodAndReturnPcAndSp(siginfo, context, &method_obj, &return_pc, &sp);
    299 
    300   // If we don't have a potential method, we're outta here.
    301   VLOG(signals) << "potential method: " << method_obj;
    302   // TODO: Check linear alloc and image.
    303   DCHECK_ALIGNED(ArtMethod::Size(kRuntimePointerSize), sizeof(void*))
    304       << "ArtMethod is not pointer aligned";
    305   if (method_obj == nullptr || !IsAligned<sizeof(void*)>(method_obj)) {
    306     VLOG(signals) << "no method";
    307     return false;
    308   }
    309 
    310   // Verify that the potential method is indeed a method.
    311   // TODO: check the GC maps to make sure it's an object.
    312   // Check that the class pointer inside the object is not null and is aligned.
    313   // No read barrier because method_obj may not be a real object.
    314   mirror::Class* cls = SafeGetDeclaringClass(method_obj);
    315   if (cls == nullptr) {
    316     VLOG(signals) << "not a class";
    317     return false;
    318   }
    319 
    320   if (!IsAligned<kObjectAlignment>(cls)) {
    321     VLOG(signals) << "not aligned";
    322     return false;
    323   }
    324 
    325   if (!SafeVerifyClassClass(cls)) {
    326     VLOG(signals) << "not a class class";
    327     return false;
    328   }
    329 
    330   const OatQuickMethodHeader* method_header = method_obj->GetOatQuickMethodHeader(return_pc);
    331 
    332   // We can be certain that this is a method now.  Check if we have a GC map
    333   // at the return PC address.
    334   if (true || kIsDebugBuild) {
    335     VLOG(signals) << "looking for dex pc for return pc " << std::hex << return_pc;
    336     uint32_t sought_offset = return_pc -
    337         reinterpret_cast<uintptr_t>(method_header->GetEntryPoint());
    338     VLOG(signals) << "pc offset: " << std::hex << sought_offset;
    339   }
    340   uint32_t dexpc = method_header->ToDexPc(method_obj, return_pc, false);
    341   VLOG(signals) << "dexpc: " << dexpc;
    342   return !check_dex_pc || dexpc != dex::kDexNoIndex;
    343 }
    344 
    345 FaultHandler::FaultHandler(FaultManager* manager) : manager_(manager) {
    346 }
    347 
    348 //
    349 // Null pointer fault handler
    350 //
    351 NullPointerHandler::NullPointerHandler(FaultManager* manager) : FaultHandler(manager) {
    352   manager_->AddHandler(this, true);
    353 }
    354 
    355 //
    356 // Suspension fault handler
    357 //
    358 SuspensionHandler::SuspensionHandler(FaultManager* manager) : FaultHandler(manager) {
    359   manager_->AddHandler(this, true);
    360 }
    361 
    362 //
    363 // Stack overflow fault handler
    364 //
    365 StackOverflowHandler::StackOverflowHandler(FaultManager* manager) : FaultHandler(manager) {
    366   manager_->AddHandler(this, true);
    367 }
    368 
    369 //
    370 // Stack trace handler, used to help get a stack trace from SIGSEGV inside of compiled code.
    371 //
    372 JavaStackTraceHandler::JavaStackTraceHandler(FaultManager* manager) : FaultHandler(manager) {
    373   manager_->AddHandler(this, false);
    374 }
    375 
    376 bool JavaStackTraceHandler::Action(int sig ATTRIBUTE_UNUSED, siginfo_t* siginfo, void* context) {
    377   // Make sure that we are in the generated code, but we may not have a dex pc.
    378   bool in_generated_code = manager_->IsInGeneratedCode(siginfo, context, false);
    379   if (in_generated_code) {
    380     LOG(ERROR) << "Dumping java stack trace for crash in generated code";
    381     ArtMethod* method = nullptr;
    382     uintptr_t return_pc = 0;
    383     uintptr_t sp = 0;
    384     Thread* self = Thread::Current();
    385 
    386     manager_->GetMethodAndReturnPcAndSp(siginfo, context, &method, &return_pc, &sp);
    387     // Inside of generated code, sp[0] is the method, so sp is the frame.
    388     self->SetTopOfStack(reinterpret_cast<ArtMethod**>(sp));
    389     self->DumpJavaStack(LOG_STREAM(ERROR));
    390   }
    391 
    392   return false;  // Return false since we want to propagate the fault to the main signal handler.
    393 }
    394 
    395 }   // namespace art
    396