diff options
author | 2021-11-12 16:27:10 +0000 | |
---|---|---|
committer | 2021-11-15 13:05:59 +0000 | |
commit | 409d1db74af9605cb8361b1487dd829820473f0f (patch) | |
tree | 0d4592801e4f42e2699812a25be7ff95b30f1388 /runtime/fault_handler.cc | |
parent | 44a1dc73ad352cb19853cd59b709df82e259cdce (diff) |
Add more checks in FaultHandler.
Make the code more robust when thinking it is dealing with an implicit
null check.
Test: test.py
Bug: 170587281
Change-Id: I5e1177377fb2dcee687a9f84693831f7d2de4b67
Diffstat (limited to 'runtime/fault_handler.cc')
-rw-r--r-- | runtime/fault_handler.cc | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/runtime/fault_handler.cc b/runtime/fault_handler.cc index bc6acec713..66fb3c7b5c 100644 --- a/runtime/fault_handler.cc +++ b/runtime/fault_handler.cc @@ -25,8 +25,11 @@ #include "base/safe_copy.h" #include "base/stl_util.h" #include "dex/dex_file_types.h" +#include "jit/jit.h" +#include "jit/jit_code_cache.h" #include "mirror/class.h" #include "mirror/object_reference.h" +#include "oat_file.h" #include "oat_quick_method_header.h" #include "sigchain.h" #include "thread-current-inl.h" @@ -265,6 +268,34 @@ void FaultManager::RemoveHandler(FaultHandler* handler) { LOG(FATAL) << "Attempted to remove non existent handler " << handler; } +static bool IsKnownPc(uintptr_t pc, ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) { + // Check whether the pc is within nterp range. + if (OatQuickMethodHeader::IsNterpPc(pc)) { + return true; + } + + // Check whether the pc is in the JIT code cache. + jit::Jit* jit = Runtime::Current()->GetJit(); + if (jit != nullptr && jit->GetCodeCache()->ContainsPc(reinterpret_cast<const void*>(pc))) { + return true; + } + + if (method->IsObsolete()) { + // Obsolete methods never happen on AOT code. + return false; + } + + // Note: at this point, we trust it's truly an ArtMethod we found at the bottom of the stack, + // and we can find its oat file through it. + const OatDexFile* oat_dex_file = method->GetDeclaringClass()->GetDexFile().GetOatDexFile(); + if (oat_dex_file != nullptr && + oat_dex_file->GetOatFile()->Contains(reinterpret_cast<const void*>(pc))) { + return true; + } + + return false; +} + // This function is called within the signal handler. It checks that // the mutator_lock is held (shared). No annotalysis is done. bool FaultManager::IsInGeneratedCode(siginfo_t* siginfo, void* context, bool check_dex_pc) { @@ -329,6 +360,11 @@ bool FaultManager::IsInGeneratedCode(siginfo_t* siginfo, void* context, bool che return false; } + if (!IsKnownPc(return_pc, method_obj)) { + VLOG(signals) << "PC not in Java code"; + return false; + } + const OatQuickMethodHeader* method_header = method_obj->GetOatQuickMethodHeader(return_pc); if (method_header == nullptr) { |