xref: /aosp_15_r20/art/runtime/fault_handler.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2008 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include "fault_handler.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include <string.h>
20*795d594fSAndroid Build Coastguard Worker #include <sys/mman.h>
21*795d594fSAndroid Build Coastguard Worker #include <sys/ucontext.h>
22*795d594fSAndroid Build Coastguard Worker 
23*795d594fSAndroid Build Coastguard Worker #include <atomic>
24*795d594fSAndroid Build Coastguard Worker 
25*795d594fSAndroid Build Coastguard Worker #include "art_method-inl.h"
26*795d594fSAndroid Build Coastguard Worker #include "base/logging.h"  // For VLOG
27*795d594fSAndroid Build Coastguard Worker #include "base/membarrier.h"
28*795d594fSAndroid Build Coastguard Worker #include "base/stl_util.h"
29*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file_types.h"
30*795d594fSAndroid Build Coastguard Worker #include "gc/heap.h"
31*795d594fSAndroid Build Coastguard Worker #include "jit/jit.h"
32*795d594fSAndroid Build Coastguard Worker #include "jit/jit_code_cache.h"
33*795d594fSAndroid Build Coastguard Worker #include "mirror/class.h"
34*795d594fSAndroid Build Coastguard Worker #include "mirror/object_reference.h"
35*795d594fSAndroid Build Coastguard Worker #include "oat/oat_file.h"
36*795d594fSAndroid Build Coastguard Worker #include "oat/oat_quick_method_header.h"
37*795d594fSAndroid Build Coastguard Worker #include "sigchain.h"
38*795d594fSAndroid Build Coastguard Worker #include "thread-current-inl.h"
39*795d594fSAndroid Build Coastguard Worker #include "verify_object-inl.h"
40*795d594fSAndroid Build Coastguard Worker 
41*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
42*795d594fSAndroid Build Coastguard Worker // Static fault manger object accessed by signal handler.
43*795d594fSAndroid Build Coastguard Worker FaultManager fault_manager;
44*795d594fSAndroid Build Coastguard Worker 
45*795d594fSAndroid Build Coastguard Worker // These need to be NO_INLINE since some debuggers do not read the inline-info to set a breakpoint
46*795d594fSAndroid Build Coastguard Worker // if they aren't.
art_sigsegv_fault()47*795d594fSAndroid Build Coastguard Worker extern "C" NO_INLINE __attribute__((visibility("default"))) void art_sigsegv_fault() {
48*795d594fSAndroid Build Coastguard Worker   // Set a breakpoint here to be informed when a SIGSEGV is unhandled by ART.
49*795d594fSAndroid Build Coastguard Worker   VLOG(signals)<< "Caught unknown SIGSEGV in ART fault handler - chaining to next handler.";
50*795d594fSAndroid Build Coastguard Worker }
art_sigbus_fault()51*795d594fSAndroid Build Coastguard Worker extern "C" NO_INLINE __attribute__((visibility("default"))) void art_sigbus_fault() {
52*795d594fSAndroid Build Coastguard Worker   // Set a breakpoint here to be informed when a SIGBUS is unhandled by ART.
53*795d594fSAndroid Build Coastguard Worker   VLOG(signals) << "Caught unknown SIGBUS in ART fault handler - chaining to next handler.";
54*795d594fSAndroid Build Coastguard Worker }
55*795d594fSAndroid Build Coastguard Worker 
56*795d594fSAndroid Build Coastguard Worker // Signal handler called on SIGSEGV.
art_sigsegv_handler(int sig,siginfo_t * info,void * context)57*795d594fSAndroid Build Coastguard Worker static bool art_sigsegv_handler(int sig, siginfo_t* info, void* context) {
58*795d594fSAndroid Build Coastguard Worker   return fault_manager.HandleSigsegvFault(sig, info, context);
59*795d594fSAndroid Build Coastguard Worker }
60*795d594fSAndroid Build Coastguard Worker 
61*795d594fSAndroid Build Coastguard Worker // Signal handler called on SIGBUS.
art_sigbus_handler(int sig,siginfo_t * info,void * context)62*795d594fSAndroid Build Coastguard Worker static bool art_sigbus_handler(int sig, siginfo_t* info, void* context) {
63*795d594fSAndroid Build Coastguard Worker   return fault_manager.HandleSigbusFault(sig, info, context);
64*795d594fSAndroid Build Coastguard Worker }
65*795d594fSAndroid Build Coastguard Worker 
FaultManager()66*795d594fSAndroid Build Coastguard Worker FaultManager::FaultManager()
67*795d594fSAndroid Build Coastguard Worker     : generated_code_ranges_lock_("FaultHandler generated code ranges lock",
68*795d594fSAndroid Build Coastguard Worker                                   LockLevel::kGenericBottomLock),
69*795d594fSAndroid Build Coastguard Worker       initialized_(false) {}
70*795d594fSAndroid Build Coastguard Worker 
~FaultManager()71*795d594fSAndroid Build Coastguard Worker FaultManager::~FaultManager() {
72*795d594fSAndroid Build Coastguard Worker }
73*795d594fSAndroid Build Coastguard Worker 
SignalCodeName(int sig,int code)74*795d594fSAndroid Build Coastguard Worker static const char* SignalCodeName(int sig, int code) {
75*795d594fSAndroid Build Coastguard Worker   if (sig == SIGSEGV) {
76*795d594fSAndroid Build Coastguard Worker     switch (code) {
77*795d594fSAndroid Build Coastguard Worker       case SEGV_MAPERR: return "SEGV_MAPERR";
78*795d594fSAndroid Build Coastguard Worker       case SEGV_ACCERR: return "SEGV_ACCERR";
79*795d594fSAndroid Build Coastguard Worker       case 8:           return "SEGV_MTEAERR";
80*795d594fSAndroid Build Coastguard Worker       case 9:           return "SEGV_MTESERR";
81*795d594fSAndroid Build Coastguard Worker       default:          return "SEGV_UNKNOWN";
82*795d594fSAndroid Build Coastguard Worker     }
83*795d594fSAndroid Build Coastguard Worker   } else if (sig == SIGBUS) {
84*795d594fSAndroid Build Coastguard Worker     switch (code) {
85*795d594fSAndroid Build Coastguard Worker       case BUS_ADRALN: return "BUS_ADRALN";
86*795d594fSAndroid Build Coastguard Worker       case BUS_ADRERR: return "BUS_ADRERR";
87*795d594fSAndroid Build Coastguard Worker       case BUS_OBJERR: return "BUS_OBJERR";
88*795d594fSAndroid Build Coastguard Worker       default:         return "BUS_UNKNOWN";
89*795d594fSAndroid Build Coastguard Worker     }
90*795d594fSAndroid Build Coastguard Worker   } else {
91*795d594fSAndroid Build Coastguard Worker     return "UNKNOWN";
92*795d594fSAndroid Build Coastguard Worker   }
93*795d594fSAndroid Build Coastguard Worker }
94*795d594fSAndroid Build Coastguard Worker 
PrintSignalInfo(std::ostream & os,siginfo_t * info)95*795d594fSAndroid Build Coastguard Worker static std::ostream& PrintSignalInfo(std::ostream& os, siginfo_t* info) {
96*795d594fSAndroid Build Coastguard Worker   os << "  si_signo: " << info->si_signo << " (" << strsignal(info->si_signo) << ")\n"
97*795d594fSAndroid Build Coastguard Worker      << "  si_code: " << info->si_code
98*795d594fSAndroid Build Coastguard Worker      << " (" << SignalCodeName(info->si_signo, info->si_code) << ")";
99*795d594fSAndroid Build Coastguard Worker   if (info->si_signo == SIGSEGV || info->si_signo == SIGBUS) {
100*795d594fSAndroid Build Coastguard Worker     os << "\n" << "  si_addr: " << info->si_addr;
101*795d594fSAndroid Build Coastguard Worker   }
102*795d594fSAndroid Build Coastguard Worker   return os;
103*795d594fSAndroid Build Coastguard Worker }
104*795d594fSAndroid Build Coastguard Worker 
Init(bool use_sig_chain)105*795d594fSAndroid Build Coastguard Worker void FaultManager::Init(bool use_sig_chain) {
106*795d594fSAndroid Build Coastguard Worker   CHECK(!initialized_);
107*795d594fSAndroid Build Coastguard Worker   if (use_sig_chain) {
108*795d594fSAndroid Build Coastguard Worker     sigset_t mask;
109*795d594fSAndroid Build Coastguard Worker     sigfillset(&mask);
110*795d594fSAndroid Build Coastguard Worker     sigdelset(&mask, SIGABRT);
111*795d594fSAndroid Build Coastguard Worker     sigdelset(&mask, SIGBUS);
112*795d594fSAndroid Build Coastguard Worker     sigdelset(&mask, SIGFPE);
113*795d594fSAndroid Build Coastguard Worker     sigdelset(&mask, SIGILL);
114*795d594fSAndroid Build Coastguard Worker     sigdelset(&mask, SIGSEGV);
115*795d594fSAndroid Build Coastguard Worker 
116*795d594fSAndroid Build Coastguard Worker     SigchainAction sa = {
117*795d594fSAndroid Build Coastguard Worker         .sc_sigaction = art_sigsegv_handler,
118*795d594fSAndroid Build Coastguard Worker         .sc_mask = mask,
119*795d594fSAndroid Build Coastguard Worker         .sc_flags = 0UL,
120*795d594fSAndroid Build Coastguard Worker     };
121*795d594fSAndroid Build Coastguard Worker 
122*795d594fSAndroid Build Coastguard Worker     AddSpecialSignalHandlerFn(SIGSEGV, &sa);
123*795d594fSAndroid Build Coastguard Worker     if (gUseUserfaultfd) {
124*795d594fSAndroid Build Coastguard Worker       sa.sc_sigaction = art_sigbus_handler;
125*795d594fSAndroid Build Coastguard Worker       AddSpecialSignalHandlerFn(SIGBUS, &sa);
126*795d594fSAndroid Build Coastguard Worker     }
127*795d594fSAndroid Build Coastguard Worker 
128*795d594fSAndroid Build Coastguard Worker     // Notify the kernel that we intend to use a specific `membarrier()` command.
129*795d594fSAndroid Build Coastguard Worker     int result = art::membarrier(MembarrierCommand::kRegisterPrivateExpedited);
130*795d594fSAndroid Build Coastguard Worker     if (result != 0) {
131*795d594fSAndroid Build Coastguard Worker       LOG(WARNING) << "FaultHandler: MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED failed: "
132*795d594fSAndroid Build Coastguard Worker                    << errno << " " << strerror(errno);
133*795d594fSAndroid Build Coastguard Worker     }
134*795d594fSAndroid Build Coastguard Worker 
135*795d594fSAndroid Build Coastguard Worker     {
136*795d594fSAndroid Build Coastguard Worker       MutexLock lock(Thread::Current(), generated_code_ranges_lock_);
137*795d594fSAndroid Build Coastguard Worker       for (size_t i = 0; i != kNumLocalGeneratedCodeRanges; ++i) {
138*795d594fSAndroid Build Coastguard Worker         GeneratedCodeRange* next = (i + 1u != kNumLocalGeneratedCodeRanges)
139*795d594fSAndroid Build Coastguard Worker             ? &generated_code_ranges_storage_[i + 1u]
140*795d594fSAndroid Build Coastguard Worker             : nullptr;
141*795d594fSAndroid Build Coastguard Worker         generated_code_ranges_storage_[i].next.store(next, std::memory_order_relaxed);
142*795d594fSAndroid Build Coastguard Worker         generated_code_ranges_storage_[i].start = nullptr;
143*795d594fSAndroid Build Coastguard Worker         generated_code_ranges_storage_[i].size = 0u;
144*795d594fSAndroid Build Coastguard Worker       }
145*795d594fSAndroid Build Coastguard Worker       free_generated_code_ranges_ = generated_code_ranges_storage_;
146*795d594fSAndroid Build Coastguard Worker     }
147*795d594fSAndroid Build Coastguard Worker 
148*795d594fSAndroid Build Coastguard Worker     initialized_ = true;
149*795d594fSAndroid Build Coastguard Worker   } else if (gUseUserfaultfd) {
150*795d594fSAndroid Build Coastguard Worker     struct sigaction act;
151*795d594fSAndroid Build Coastguard Worker     std::memset(&act, '\0', sizeof(act));
152*795d594fSAndroid Build Coastguard Worker     act.sa_flags = SA_SIGINFO | SA_RESTART;
153*795d594fSAndroid Build Coastguard Worker     act.sa_sigaction = [](int sig, siginfo_t* info, void* context) {
154*795d594fSAndroid Build Coastguard Worker       if (!art_sigbus_handler(sig, info, context)) {
155*795d594fSAndroid Build Coastguard Worker         std::ostringstream oss;
156*795d594fSAndroid Build Coastguard Worker         PrintSignalInfo(oss, info);
157*795d594fSAndroid Build Coastguard Worker         LOG(FATAL) << "Couldn't handle SIGBUS fault:"
158*795d594fSAndroid Build Coastguard Worker                    << "\n"
159*795d594fSAndroid Build Coastguard Worker                    << oss.str();
160*795d594fSAndroid Build Coastguard Worker       }
161*795d594fSAndroid Build Coastguard Worker     };
162*795d594fSAndroid Build Coastguard Worker     if (sigaction(SIGBUS, &act, nullptr)) {
163*795d594fSAndroid Build Coastguard Worker       LOG(FATAL) << "Fault handler for SIGBUS couldn't be setup: " << strerror(errno);
164*795d594fSAndroid Build Coastguard Worker     }
165*795d594fSAndroid Build Coastguard Worker   }
166*795d594fSAndroid Build Coastguard Worker }
167*795d594fSAndroid Build Coastguard Worker 
Release()168*795d594fSAndroid Build Coastguard Worker void FaultManager::Release() {
169*795d594fSAndroid Build Coastguard Worker   if (initialized_) {
170*795d594fSAndroid Build Coastguard Worker     RemoveSpecialSignalHandlerFn(SIGSEGV, art_sigsegv_handler);
171*795d594fSAndroid Build Coastguard Worker     if (gUseUserfaultfd) {
172*795d594fSAndroid Build Coastguard Worker       RemoveSpecialSignalHandlerFn(SIGBUS, art_sigbus_handler);
173*795d594fSAndroid Build Coastguard Worker     }
174*795d594fSAndroid Build Coastguard Worker     initialized_ = false;
175*795d594fSAndroid Build Coastguard Worker   }
176*795d594fSAndroid Build Coastguard Worker }
177*795d594fSAndroid Build Coastguard Worker 
Shutdown()178*795d594fSAndroid Build Coastguard Worker void FaultManager::Shutdown() {
179*795d594fSAndroid Build Coastguard Worker   if (initialized_) {
180*795d594fSAndroid Build Coastguard Worker     Release();
181*795d594fSAndroid Build Coastguard Worker 
182*795d594fSAndroid Build Coastguard Worker     // Free all handlers.
183*795d594fSAndroid Build Coastguard Worker     STLDeleteElements(&generated_code_handlers_);
184*795d594fSAndroid Build Coastguard Worker     STLDeleteElements(&other_handlers_);
185*795d594fSAndroid Build Coastguard Worker 
186*795d594fSAndroid Build Coastguard Worker     // Delete remaining code ranges if any (such as nterp code or oat code from
187*795d594fSAndroid Build Coastguard Worker     // oat files that have not been unloaded, including boot image oat files).
188*795d594fSAndroid Build Coastguard Worker     MutexLock lock(Thread::Current(), generated_code_ranges_lock_);
189*795d594fSAndroid Build Coastguard Worker     GeneratedCodeRange* range = generated_code_ranges_.load(std::memory_order_acquire);
190*795d594fSAndroid Build Coastguard Worker     generated_code_ranges_.store(nullptr, std::memory_order_release);
191*795d594fSAndroid Build Coastguard Worker     while (range != nullptr) {
192*795d594fSAndroid Build Coastguard Worker       GeneratedCodeRange* next_range = range->next.load(std::memory_order_relaxed);
193*795d594fSAndroid Build Coastguard Worker       std::less<GeneratedCodeRange*> less;
194*795d594fSAndroid Build Coastguard Worker       if (!less(range, generated_code_ranges_storage_) &&
195*795d594fSAndroid Build Coastguard Worker           less(range, generated_code_ranges_storage_ + kNumLocalGeneratedCodeRanges)) {
196*795d594fSAndroid Build Coastguard Worker         // Nothing to do - not adding `range` to the `free_generated_code_ranges_` anymore.
197*795d594fSAndroid Build Coastguard Worker       } else {
198*795d594fSAndroid Build Coastguard Worker         // Range is not in the `generated_code_ranges_storage_`.
199*795d594fSAndroid Build Coastguard Worker         delete range;
200*795d594fSAndroid Build Coastguard Worker       }
201*795d594fSAndroid Build Coastguard Worker       range = next_range;
202*795d594fSAndroid Build Coastguard Worker     }
203*795d594fSAndroid Build Coastguard Worker   }
204*795d594fSAndroid Build Coastguard Worker }
205*795d594fSAndroid Build Coastguard Worker 
HandleFaultByOtherHandlers(int sig,siginfo_t * info,void * context)206*795d594fSAndroid Build Coastguard Worker bool FaultManager::HandleFaultByOtherHandlers(int sig, siginfo_t* info, void* context) {
207*795d594fSAndroid Build Coastguard Worker   if (other_handlers_.empty()) {
208*795d594fSAndroid Build Coastguard Worker     return false;
209*795d594fSAndroid Build Coastguard Worker   }
210*795d594fSAndroid Build Coastguard Worker 
211*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
212*795d594fSAndroid Build Coastguard Worker 
213*795d594fSAndroid Build Coastguard Worker   DCHECK(self != nullptr);
214*795d594fSAndroid Build Coastguard Worker   DCHECK(Runtime::Current() != nullptr);
215*795d594fSAndroid Build Coastguard Worker   DCHECK(Runtime::Current()->IsStarted());
216*795d594fSAndroid Build Coastguard Worker   for (const auto& handler : other_handlers_) {
217*795d594fSAndroid Build Coastguard Worker     if (handler->Action(sig, info, context)) {
218*795d594fSAndroid Build Coastguard Worker       return true;
219*795d594fSAndroid Build Coastguard Worker     }
220*795d594fSAndroid Build Coastguard Worker   }
221*795d594fSAndroid Build Coastguard Worker   return false;
222*795d594fSAndroid Build Coastguard Worker }
223*795d594fSAndroid Build Coastguard Worker 
HandleSigbusFault(int sig,siginfo_t * info,void * context)224*795d594fSAndroid Build Coastguard Worker bool FaultManager::HandleSigbusFault(int sig, siginfo_t* info, [[maybe_unused]] void* context) {
225*795d594fSAndroid Build Coastguard Worker   DCHECK_EQ(sig, SIGBUS);
226*795d594fSAndroid Build Coastguard Worker   if (VLOG_IS_ON(signals)) {
227*795d594fSAndroid Build Coastguard Worker     PrintSignalInfo(VLOG_STREAM(signals) << "Handling SIGBUS fault:\n", info);
228*795d594fSAndroid Build Coastguard Worker   }
229*795d594fSAndroid Build Coastguard Worker 
230*795d594fSAndroid Build Coastguard Worker #ifdef TEST_NESTED_SIGNAL
231*795d594fSAndroid Build Coastguard Worker   // Simulate a crash in a handler.
232*795d594fSAndroid Build Coastguard Worker   raise(SIGBUS);
233*795d594fSAndroid Build Coastguard Worker #endif
234*795d594fSAndroid Build Coastguard Worker   if (Runtime::Current()->GetHeap()->MarkCompactCollector()->SigbusHandler(info)) {
235*795d594fSAndroid Build Coastguard Worker     return true;
236*795d594fSAndroid Build Coastguard Worker   }
237*795d594fSAndroid Build Coastguard Worker 
238*795d594fSAndroid Build Coastguard Worker   // Set a breakpoint in this function to catch unhandled signals.
239*795d594fSAndroid Build Coastguard Worker   art_sigbus_fault();
240*795d594fSAndroid Build Coastguard Worker   return false;
241*795d594fSAndroid Build Coastguard Worker }
242*795d594fSAndroid Build Coastguard Worker 
CheckForUnrecognizedImplicitSuspendCheckInBootImage(siginfo_t * siginfo,void * context)243*795d594fSAndroid Build Coastguard Worker inline void FaultManager::CheckForUnrecognizedImplicitSuspendCheckInBootImage(
244*795d594fSAndroid Build Coastguard Worker     siginfo_t* siginfo, void* context) {
245*795d594fSAndroid Build Coastguard Worker   CHECK_EQ(kRuntimeQuickCodeISA, InstructionSet::kArm64);
246*795d594fSAndroid Build Coastguard Worker   uintptr_t fault_pc = GetFaultPc(siginfo, context);
247*795d594fSAndroid Build Coastguard Worker   if (fault_pc == 0u || !IsUint<32>(fault_pc) || !IsAligned<4u>(fault_pc)) {
248*795d594fSAndroid Build Coastguard Worker     return;
249*795d594fSAndroid Build Coastguard Worker   }
250*795d594fSAndroid Build Coastguard Worker   Runtime* runtime = Runtime::Current();
251*795d594fSAndroid Build Coastguard Worker   if (runtime == nullptr) {
252*795d594fSAndroid Build Coastguard Worker     return;
253*795d594fSAndroid Build Coastguard Worker   }
254*795d594fSAndroid Build Coastguard Worker   gc::Heap* heap = runtime->GetHeap();
255*795d594fSAndroid Build Coastguard Worker   if (heap == nullptr ||
256*795d594fSAndroid Build Coastguard Worker       fault_pc < heap->GetBootImagesStartAddress() ||
257*795d594fSAndroid Build Coastguard Worker       fault_pc - heap->GetBootImagesStartAddress() >= heap->GetBootImagesSize() ||
258*795d594fSAndroid Build Coastguard Worker       reinterpret_cast<uint32_t*>(fault_pc)[0] != /*LDR x21. [x21]*/ 0xf94002b5u) {
259*795d594fSAndroid Build Coastguard Worker     return;
260*795d594fSAndroid Build Coastguard Worker   }
261*795d594fSAndroid Build Coastguard Worker   std::ostringstream oss;
262*795d594fSAndroid Build Coastguard Worker   oss << "Failed to recognize implicit suspend check at 0x" << std::hex << fault_pc << "; ";
263*795d594fSAndroid Build Coastguard Worker   Thread* thread = Thread::Current();
264*795d594fSAndroid Build Coastguard Worker   if (thread == nullptr) {
265*795d594fSAndroid Build Coastguard Worker     oss << "null thread";
266*795d594fSAndroid Build Coastguard Worker   } else {
267*795d594fSAndroid Build Coastguard Worker     oss << "thread state = " << thread->GetState() << std::boolalpha
268*795d594fSAndroid Build Coastguard Worker         << "; mutator lock shared held = " << Locks::mutator_lock_->IsSharedHeld(thread);
269*795d594fSAndroid Build Coastguard Worker   }
270*795d594fSAndroid Build Coastguard Worker   oss << "; code ranges = {";
271*795d594fSAndroid Build Coastguard Worker   GeneratedCodeRange* range = generated_code_ranges_.load(std::memory_order_acquire);
272*795d594fSAndroid Build Coastguard Worker   const char* s = "";
273*795d594fSAndroid Build Coastguard Worker   while (range != nullptr) {
274*795d594fSAndroid Build Coastguard Worker     oss << s << "{" << range->start << ", " << range->size << "}";
275*795d594fSAndroid Build Coastguard Worker     s = ", ";
276*795d594fSAndroid Build Coastguard Worker     range = range->next.load(std::memory_order_relaxed);
277*795d594fSAndroid Build Coastguard Worker   }
278*795d594fSAndroid Build Coastguard Worker   oss << "}";
279*795d594fSAndroid Build Coastguard Worker   LOG(FATAL) << oss.str();
280*795d594fSAndroid Build Coastguard Worker   UNREACHABLE();
281*795d594fSAndroid Build Coastguard Worker }
282*795d594fSAndroid Build Coastguard Worker 
283*795d594fSAndroid Build Coastguard Worker 
HandleSigsegvFault(int sig,siginfo_t * info,void * context)284*795d594fSAndroid Build Coastguard Worker bool FaultManager::HandleSigsegvFault(int sig, siginfo_t* info, void* context) {
285*795d594fSAndroid Build Coastguard Worker   if (VLOG_IS_ON(signals)) {
286*795d594fSAndroid Build Coastguard Worker     PrintSignalInfo(VLOG_STREAM(signals) << "Handling SIGSEGV fault:\n", info);
287*795d594fSAndroid Build Coastguard Worker   }
288*795d594fSAndroid Build Coastguard Worker 
289*795d594fSAndroid Build Coastguard Worker #ifdef TEST_NESTED_SIGNAL
290*795d594fSAndroid Build Coastguard Worker   // Simulate a crash in a handler.
291*795d594fSAndroid Build Coastguard Worker   raise(SIGSEGV);
292*795d594fSAndroid Build Coastguard Worker #endif
293*795d594fSAndroid Build Coastguard Worker 
294*795d594fSAndroid Build Coastguard Worker   if (IsInGeneratedCode(info, context)) {
295*795d594fSAndroid Build Coastguard Worker     VLOG(signals) << "in generated code, looking for handler";
296*795d594fSAndroid Build Coastguard Worker     for (const auto& handler : generated_code_handlers_) {
297*795d594fSAndroid Build Coastguard Worker       VLOG(signals) << "invoking Action on handler " << handler;
298*795d594fSAndroid Build Coastguard Worker       if (handler->Action(sig, info, context)) {
299*795d594fSAndroid Build Coastguard Worker         // We have handled a signal so it's time to return from the
300*795d594fSAndroid Build Coastguard Worker         // signal handler to the appropriate place.
301*795d594fSAndroid Build Coastguard Worker         return true;
302*795d594fSAndroid Build Coastguard Worker       }
303*795d594fSAndroid Build Coastguard Worker     }
304*795d594fSAndroid Build Coastguard Worker   } else if (kRuntimeQuickCodeISA == InstructionSet::kArm64) {
305*795d594fSAndroid Build Coastguard Worker     CheckForUnrecognizedImplicitSuspendCheckInBootImage(info, context);
306*795d594fSAndroid Build Coastguard Worker   }
307*795d594fSAndroid Build Coastguard Worker 
308*795d594fSAndroid Build Coastguard Worker   // We hit a signal we didn't handle.  This might be something for which
309*795d594fSAndroid Build Coastguard Worker   // we can give more information about so call all registered handlers to
310*795d594fSAndroid Build Coastguard Worker   // see if it is.
311*795d594fSAndroid Build Coastguard Worker   if (HandleFaultByOtherHandlers(sig, info, context)) {
312*795d594fSAndroid Build Coastguard Worker     return true;
313*795d594fSAndroid Build Coastguard Worker   }
314*795d594fSAndroid Build Coastguard Worker 
315*795d594fSAndroid Build Coastguard Worker   // Set a breakpoint in this function to catch unhandled signals.
316*795d594fSAndroid Build Coastguard Worker   art_sigsegv_fault();
317*795d594fSAndroid Build Coastguard Worker   return false;
318*795d594fSAndroid Build Coastguard Worker }
319*795d594fSAndroid Build Coastguard Worker 
AddHandler(FaultHandler * handler,bool generated_code)320*795d594fSAndroid Build Coastguard Worker void FaultManager::AddHandler(FaultHandler* handler, bool generated_code) {
321*795d594fSAndroid Build Coastguard Worker   DCHECK(initialized_);
322*795d594fSAndroid Build Coastguard Worker   if (generated_code) {
323*795d594fSAndroid Build Coastguard Worker     generated_code_handlers_.push_back(handler);
324*795d594fSAndroid Build Coastguard Worker   } else {
325*795d594fSAndroid Build Coastguard Worker     other_handlers_.push_back(handler);
326*795d594fSAndroid Build Coastguard Worker   }
327*795d594fSAndroid Build Coastguard Worker }
328*795d594fSAndroid Build Coastguard Worker 
RemoveHandler(FaultHandler * handler)329*795d594fSAndroid Build Coastguard Worker void FaultManager::RemoveHandler(FaultHandler* handler) {
330*795d594fSAndroid Build Coastguard Worker   auto it = std::find(generated_code_handlers_.begin(), generated_code_handlers_.end(), handler);
331*795d594fSAndroid Build Coastguard Worker   if (it != generated_code_handlers_.end()) {
332*795d594fSAndroid Build Coastguard Worker     generated_code_handlers_.erase(it);
333*795d594fSAndroid Build Coastguard Worker     return;
334*795d594fSAndroid Build Coastguard Worker   }
335*795d594fSAndroid Build Coastguard Worker   auto it2 = std::find(other_handlers_.begin(), other_handlers_.end(), handler);
336*795d594fSAndroid Build Coastguard Worker   if (it2 != other_handlers_.end()) {
337*795d594fSAndroid Build Coastguard Worker     other_handlers_.erase(it2);
338*795d594fSAndroid Build Coastguard Worker     return;
339*795d594fSAndroid Build Coastguard Worker   }
340*795d594fSAndroid Build Coastguard Worker   LOG(FATAL) << "Attempted to remove non existent handler " << handler;
341*795d594fSAndroid Build Coastguard Worker }
342*795d594fSAndroid Build Coastguard Worker 
CreateGeneratedCodeRange(const void * start,size_t size)343*795d594fSAndroid Build Coastguard Worker inline FaultManager::GeneratedCodeRange* FaultManager::CreateGeneratedCodeRange(
344*795d594fSAndroid Build Coastguard Worker     const void* start, size_t size) {
345*795d594fSAndroid Build Coastguard Worker   GeneratedCodeRange* range = free_generated_code_ranges_;
346*795d594fSAndroid Build Coastguard Worker   if (range != nullptr) {
347*795d594fSAndroid Build Coastguard Worker     std::less<GeneratedCodeRange*> less;
348*795d594fSAndroid Build Coastguard Worker     DCHECK(!less(range, generated_code_ranges_storage_));
349*795d594fSAndroid Build Coastguard Worker     DCHECK(less(range, generated_code_ranges_storage_ + kNumLocalGeneratedCodeRanges));
350*795d594fSAndroid Build Coastguard Worker     range->start = start;
351*795d594fSAndroid Build Coastguard Worker     range->size = size;
352*795d594fSAndroid Build Coastguard Worker     free_generated_code_ranges_ = range->next.load(std::memory_order_relaxed);
353*795d594fSAndroid Build Coastguard Worker     range->next.store(nullptr, std::memory_order_relaxed);
354*795d594fSAndroid Build Coastguard Worker     return range;
355*795d594fSAndroid Build Coastguard Worker   } else {
356*795d594fSAndroid Build Coastguard Worker     return new GeneratedCodeRange{nullptr, start, size};
357*795d594fSAndroid Build Coastguard Worker   }
358*795d594fSAndroid Build Coastguard Worker }
359*795d594fSAndroid Build Coastguard Worker 
FreeGeneratedCodeRange(GeneratedCodeRange * range)360*795d594fSAndroid Build Coastguard Worker inline void FaultManager::FreeGeneratedCodeRange(GeneratedCodeRange* range) {
361*795d594fSAndroid Build Coastguard Worker   std::less<GeneratedCodeRange*> less;
362*795d594fSAndroid Build Coastguard Worker   if (!less(range, generated_code_ranges_storage_) &&
363*795d594fSAndroid Build Coastguard Worker       less(range, generated_code_ranges_storage_ + kNumLocalGeneratedCodeRanges)) {
364*795d594fSAndroid Build Coastguard Worker     MutexLock lock(Thread::Current(), generated_code_ranges_lock_);
365*795d594fSAndroid Build Coastguard Worker     range->start = nullptr;
366*795d594fSAndroid Build Coastguard Worker     range->size = 0u;
367*795d594fSAndroid Build Coastguard Worker     range->next.store(free_generated_code_ranges_, std::memory_order_relaxed);
368*795d594fSAndroid Build Coastguard Worker     free_generated_code_ranges_ = range;
369*795d594fSAndroid Build Coastguard Worker   } else {
370*795d594fSAndroid Build Coastguard Worker     // Range is not in the `generated_code_ranges_storage_`.
371*795d594fSAndroid Build Coastguard Worker     delete range;
372*795d594fSAndroid Build Coastguard Worker   }
373*795d594fSAndroid Build Coastguard Worker }
374*795d594fSAndroid Build Coastguard Worker 
AddGeneratedCodeRange(const void * start,size_t size)375*795d594fSAndroid Build Coastguard Worker void FaultManager::AddGeneratedCodeRange(const void* start, size_t size) {
376*795d594fSAndroid Build Coastguard Worker   GeneratedCodeRange* new_range = nullptr;
377*795d594fSAndroid Build Coastguard Worker   {
378*795d594fSAndroid Build Coastguard Worker     MutexLock lock(Thread::Current(), generated_code_ranges_lock_);
379*795d594fSAndroid Build Coastguard Worker     new_range = CreateGeneratedCodeRange(start, size);
380*795d594fSAndroid Build Coastguard Worker     GeneratedCodeRange* old_head = generated_code_ranges_.load(std::memory_order_relaxed);
381*795d594fSAndroid Build Coastguard Worker     new_range->next.store(old_head, std::memory_order_relaxed);
382*795d594fSAndroid Build Coastguard Worker     generated_code_ranges_.store(new_range, std::memory_order_release);
383*795d594fSAndroid Build Coastguard Worker   }
384*795d594fSAndroid Build Coastguard Worker 
385*795d594fSAndroid Build Coastguard Worker   // The above release operation on `generated_code_ranges_` with an acquire operation
386*795d594fSAndroid Build Coastguard Worker   // on the same atomic object in `IsInGeneratedCode()` ensures the correct memory
387*795d594fSAndroid Build Coastguard Worker   // visibility for the contents of `*new_range` for any thread that loads the value
388*795d594fSAndroid Build Coastguard Worker   // written above (or a value written by a release sequence headed by that write).
389*795d594fSAndroid Build Coastguard Worker   //
390*795d594fSAndroid Build Coastguard Worker   // However, we also need to ensure that any thread that encounters a segmentation
391*795d594fSAndroid Build Coastguard Worker   // fault in the provided range shall actually see the written value. For JIT code
392*795d594fSAndroid Build Coastguard Worker   // cache and nterp, the registration happens while the process is single-threaded
393*795d594fSAndroid Build Coastguard Worker   // but the synchronization is more complicated for code in oat files.
394*795d594fSAndroid Build Coastguard Worker   //
395*795d594fSAndroid Build Coastguard Worker   // Threads that load classes register dex files under the `Locks::dex_lock_` and
396*795d594fSAndroid Build Coastguard Worker   // the first one to register a dex file with a given oat file shall add the oat
397*795d594fSAndroid Build Coastguard Worker   // code range; the memory visibility for these threads is guaranteed by the lock.
398*795d594fSAndroid Build Coastguard Worker   // However a thread that did not try to load a class with oat code can execute the
399*795d594fSAndroid Build Coastguard Worker   // code if a direct or indirect reference to such class escapes from one of the
400*795d594fSAndroid Build Coastguard Worker   // threads that loaded it. Use `membarrier()` for memory visibility in this case.
401*795d594fSAndroid Build Coastguard Worker   art::membarrier(MembarrierCommand::kPrivateExpedited);
402*795d594fSAndroid Build Coastguard Worker }
403*795d594fSAndroid Build Coastguard Worker 
RemoveGeneratedCodeRange(const void * start,size_t size)404*795d594fSAndroid Build Coastguard Worker void FaultManager::RemoveGeneratedCodeRange(const void* start, size_t size) {
405*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
406*795d594fSAndroid Build Coastguard Worker   GeneratedCodeRange* range = nullptr;
407*795d594fSAndroid Build Coastguard Worker   {
408*795d594fSAndroid Build Coastguard Worker     MutexLock lock(self, generated_code_ranges_lock_);
409*795d594fSAndroid Build Coastguard Worker     std::atomic<GeneratedCodeRange*>* before = &generated_code_ranges_;
410*795d594fSAndroid Build Coastguard Worker     range = before->load(std::memory_order_relaxed);
411*795d594fSAndroid Build Coastguard Worker     while (range != nullptr && range->start != start) {
412*795d594fSAndroid Build Coastguard Worker       before = &range->next;
413*795d594fSAndroid Build Coastguard Worker       range = before->load(std::memory_order_relaxed);
414*795d594fSAndroid Build Coastguard Worker     }
415*795d594fSAndroid Build Coastguard Worker     if (range != nullptr) {
416*795d594fSAndroid Build Coastguard Worker       GeneratedCodeRange* next = range->next.load(std::memory_order_relaxed);
417*795d594fSAndroid Build Coastguard Worker       if (before == &generated_code_ranges_) {
418*795d594fSAndroid Build Coastguard Worker         // Relaxed store directly to `generated_code_ranges_` would not satisfy
419*795d594fSAndroid Build Coastguard Worker         // conditions for a release sequence, so we need to use store-release.
420*795d594fSAndroid Build Coastguard Worker         before->store(next, std::memory_order_release);
421*795d594fSAndroid Build Coastguard Worker       } else {
422*795d594fSAndroid Build Coastguard Worker         // In the middle of the list, we can use a relaxed store as we're not
423*795d594fSAndroid Build Coastguard Worker         // publishing any newly written memory to potential reader threads.
424*795d594fSAndroid Build Coastguard Worker         // Whether they see the removed node or not is unimportant as we should
425*795d594fSAndroid Build Coastguard Worker         // not execute that code anymore. We're keeping the `next` link of the
426*795d594fSAndroid Build Coastguard Worker         // removed node, so that concurrent walk can use it to reach remaining
427*795d594fSAndroid Build Coastguard Worker         // retained nodes, if any.
428*795d594fSAndroid Build Coastguard Worker         before->store(next, std::memory_order_relaxed);
429*795d594fSAndroid Build Coastguard Worker       }
430*795d594fSAndroid Build Coastguard Worker     }
431*795d594fSAndroid Build Coastguard Worker   }
432*795d594fSAndroid Build Coastguard Worker   CHECK(range != nullptr);
433*795d594fSAndroid Build Coastguard Worker   DCHECK_EQ(range->start, start);
434*795d594fSAndroid Build Coastguard Worker   CHECK_EQ(range->size, size);
435*795d594fSAndroid Build Coastguard Worker 
436*795d594fSAndroid Build Coastguard Worker   Runtime* runtime = Runtime::Current();
437*795d594fSAndroid Build Coastguard Worker   CHECK(runtime != nullptr);
438*795d594fSAndroid Build Coastguard Worker   if (runtime->IsStarted() && runtime->GetThreadList() != nullptr) {
439*795d594fSAndroid Build Coastguard Worker     // Run a checkpoint before deleting the range to ensure that no thread holds a
440*795d594fSAndroid Build Coastguard Worker     // pointer to the removed range while walking the list in `IsInGeneratedCode()`.
441*795d594fSAndroid Build Coastguard Worker     // That walk is guarded by checking that the thread is `Runnable`, so any walk
442*795d594fSAndroid Build Coastguard Worker     // started before the removal shall be done when running the checkpoint and the
443*795d594fSAndroid Build Coastguard Worker     // checkpoint also ensures the correct memory visibility of `next` links,
444*795d594fSAndroid Build Coastguard Worker     // so the thread shall not see the pointer during future walks.
445*795d594fSAndroid Build Coastguard Worker 
446*795d594fSAndroid Build Coastguard Worker     // This function is currently called in different mutex and thread states.
447*795d594fSAndroid Build Coastguard Worker     // Semi-space GC performs the cleanup during its `MarkingPhase()` while holding
448*795d594fSAndroid Build Coastguard Worker     // the mutator exclusively, so we do not need a checkpoint. All other GCs perform
449*795d594fSAndroid Build Coastguard Worker     // the cleanup in their `ReclaimPhase()` while holding the mutator lock as shared
450*795d594fSAndroid Build Coastguard Worker     // and it's safe to release and re-acquire the mutator lock. Despite holding the
451*795d594fSAndroid Build Coastguard Worker     // mutator lock as shared, the thread is not always marked as `Runnable`.
452*795d594fSAndroid Build Coastguard Worker     // TODO: Clean up state transitions in different GC implementations. b/259440389
453*795d594fSAndroid Build Coastguard Worker     if (Locks::mutator_lock_->IsExclusiveHeld(self)) {
454*795d594fSAndroid Build Coastguard Worker       // We do not need a checkpoint because no other thread is Runnable.
455*795d594fSAndroid Build Coastguard Worker     } else {
456*795d594fSAndroid Build Coastguard Worker       DCHECK(Locks::mutator_lock_->IsSharedHeld(self));
457*795d594fSAndroid Build Coastguard Worker       // Use explicit state transitions or unlock/lock.
458*795d594fSAndroid Build Coastguard Worker       bool runnable = (self->GetState() == ThreadState::kRunnable);
459*795d594fSAndroid Build Coastguard Worker       if (runnable) {
460*795d594fSAndroid Build Coastguard Worker         self->TransitionFromRunnableToSuspended(ThreadState::kNative);
461*795d594fSAndroid Build Coastguard Worker       } else {
462*795d594fSAndroid Build Coastguard Worker         Locks::mutator_lock_->SharedUnlock(self);
463*795d594fSAndroid Build Coastguard Worker       }
464*795d594fSAndroid Build Coastguard Worker       DCHECK(!Locks::mutator_lock_->IsSharedHeld(self));
465*795d594fSAndroid Build Coastguard Worker       runtime->GetThreadList()->RunEmptyCheckpoint();
466*795d594fSAndroid Build Coastguard Worker       if (runnable) {
467*795d594fSAndroid Build Coastguard Worker         self->TransitionFromSuspendedToRunnable();
468*795d594fSAndroid Build Coastguard Worker       } else {
469*795d594fSAndroid Build Coastguard Worker         Locks::mutator_lock_->SharedLock(self);
470*795d594fSAndroid Build Coastguard Worker       }
471*795d594fSAndroid Build Coastguard Worker     }
472*795d594fSAndroid Build Coastguard Worker   }
473*795d594fSAndroid Build Coastguard Worker   FreeGeneratedCodeRange(range);
474*795d594fSAndroid Build Coastguard Worker }
475*795d594fSAndroid Build Coastguard Worker 
476*795d594fSAndroid Build Coastguard Worker // This function is called within the signal handler. It checks that the thread
477*795d594fSAndroid Build Coastguard Worker // is `Runnable`, the `mutator_lock_` is held (shared) and the fault PC is in one
478*795d594fSAndroid Build Coastguard Worker // of the registered generated code ranges. No annotalysis is done.
IsInGeneratedCode(siginfo_t * siginfo,void * context)479*795d594fSAndroid Build Coastguard Worker bool FaultManager::IsInGeneratedCode(siginfo_t* siginfo, void* context) {
480*795d594fSAndroid Build Coastguard Worker   // We can only be running Java code in the current thread if it
481*795d594fSAndroid Build Coastguard Worker   // is in Runnable state.
482*795d594fSAndroid Build Coastguard Worker   VLOG(signals) << "Checking for generated code";
483*795d594fSAndroid Build Coastguard Worker   Thread* thread = Thread::Current();
484*795d594fSAndroid Build Coastguard Worker   if (thread == nullptr) {
485*795d594fSAndroid Build Coastguard Worker     VLOG(signals) << "no current thread";
486*795d594fSAndroid Build Coastguard Worker     return false;
487*795d594fSAndroid Build Coastguard Worker   }
488*795d594fSAndroid Build Coastguard Worker 
489*795d594fSAndroid Build Coastguard Worker   ThreadState state = thread->GetState();
490*795d594fSAndroid Build Coastguard Worker   if (state != ThreadState::kRunnable) {
491*795d594fSAndroid Build Coastguard Worker     VLOG(signals) << "not runnable";
492*795d594fSAndroid Build Coastguard Worker     return false;
493*795d594fSAndroid Build Coastguard Worker   }
494*795d594fSAndroid Build Coastguard Worker 
495*795d594fSAndroid Build Coastguard Worker   // Current thread is runnable.
496*795d594fSAndroid Build Coastguard Worker   // Make sure it has the mutator lock.
497*795d594fSAndroid Build Coastguard Worker   if (!Locks::mutator_lock_->IsSharedHeld(thread)) {
498*795d594fSAndroid Build Coastguard Worker     VLOG(signals) << "no lock";
499*795d594fSAndroid Build Coastguard Worker     return false;
500*795d594fSAndroid Build Coastguard Worker   }
501*795d594fSAndroid Build Coastguard Worker 
502*795d594fSAndroid Build Coastguard Worker   uintptr_t fault_pc = GetFaultPc(siginfo, context);
503*795d594fSAndroid Build Coastguard Worker   if (fault_pc == 0u) {
504*795d594fSAndroid Build Coastguard Worker     VLOG(signals) << "no fault PC";
505*795d594fSAndroid Build Coastguard Worker     return false;
506*795d594fSAndroid Build Coastguard Worker   }
507*795d594fSAndroid Build Coastguard Worker 
508*795d594fSAndroid Build Coastguard Worker   // Walk over the list of registered code ranges.
509*795d594fSAndroid Build Coastguard Worker   GeneratedCodeRange* range = generated_code_ranges_.load(std::memory_order_acquire);
510*795d594fSAndroid Build Coastguard Worker   while (range != nullptr) {
511*795d594fSAndroid Build Coastguard Worker     if (fault_pc - reinterpret_cast<uintptr_t>(range->start) < range->size) {
512*795d594fSAndroid Build Coastguard Worker       return true;
513*795d594fSAndroid Build Coastguard Worker     }
514*795d594fSAndroid Build Coastguard Worker     // We may or may not see ranges that were concurrently removed, depending
515*795d594fSAndroid Build Coastguard Worker     // on when the relaxed writes of the `next` links become visible. However,
516*795d594fSAndroid Build Coastguard Worker     // even if we're currently at a node that is being removed, we shall visit
517*795d594fSAndroid Build Coastguard Worker     // all remaining ranges that are not being removed as the removed nodes
518*795d594fSAndroid Build Coastguard Worker     // retain the `next` link at the time of removal (which may lead to other
519*795d594fSAndroid Build Coastguard Worker     // removed nodes before reaching remaining retained nodes, if any). Correct
520*795d594fSAndroid Build Coastguard Worker     // memory visibility of `start` and `size` fields of the visited ranges is
521*795d594fSAndroid Build Coastguard Worker     // ensured by the release and acquire operations on `generated_code_ranges_`.
522*795d594fSAndroid Build Coastguard Worker     range = range->next.load(std::memory_order_relaxed);
523*795d594fSAndroid Build Coastguard Worker   }
524*795d594fSAndroid Build Coastguard Worker   return false;
525*795d594fSAndroid Build Coastguard Worker }
526*795d594fSAndroid Build Coastguard Worker 
FaultHandler(FaultManager * manager)527*795d594fSAndroid Build Coastguard Worker FaultHandler::FaultHandler(FaultManager* manager) : manager_(manager) {
528*795d594fSAndroid Build Coastguard Worker }
529*795d594fSAndroid Build Coastguard Worker 
530*795d594fSAndroid Build Coastguard Worker //
531*795d594fSAndroid Build Coastguard Worker // Null pointer fault handler
532*795d594fSAndroid Build Coastguard Worker //
NullPointerHandler(FaultManager * manager)533*795d594fSAndroid Build Coastguard Worker NullPointerHandler::NullPointerHandler(FaultManager* manager) : FaultHandler(manager) {
534*795d594fSAndroid Build Coastguard Worker   manager_->AddHandler(this, true);
535*795d594fSAndroid Build Coastguard Worker }
536*795d594fSAndroid Build Coastguard Worker 
IsValidMethod(ArtMethod * method)537*795d594fSAndroid Build Coastguard Worker bool NullPointerHandler::IsValidMethod(ArtMethod* method) {
538*795d594fSAndroid Build Coastguard Worker   // At this point we know that the thread is `Runnable` and the PC is in one of
539*795d594fSAndroid Build Coastguard Worker   // the registered code ranges. The `method` was read from the top of the stack
540*795d594fSAndroid Build Coastguard Worker   // and should really point to an actual `ArtMethod`, unless we're crashing during
541*795d594fSAndroid Build Coastguard Worker   // prologue or epilogue, or somehow managed to jump to the compiled code by some
542*795d594fSAndroid Build Coastguard Worker   // unexpected path, other than method invoke or exception delivery. We do a few
543*795d594fSAndroid Build Coastguard Worker   // quick checks without guarding from another fault.
544*795d594fSAndroid Build Coastguard Worker   VLOG(signals) << "potential method: " << method;
545*795d594fSAndroid Build Coastguard Worker 
546*795d594fSAndroid Build Coastguard Worker   static_assert(IsAligned<sizeof(void*)>(ArtMethod::Size(kRuntimePointerSize)));
547*795d594fSAndroid Build Coastguard Worker   if (method == nullptr || !IsAligned<sizeof(void*)>(method)) {
548*795d594fSAndroid Build Coastguard Worker     VLOG(signals) << ((method == nullptr) ? "null method" : "unaligned method");
549*795d594fSAndroid Build Coastguard Worker     return false;
550*795d594fSAndroid Build Coastguard Worker   }
551*795d594fSAndroid Build Coastguard Worker 
552*795d594fSAndroid Build Coastguard Worker   // Check that the presumed method actually points to a class. Read barriers
553*795d594fSAndroid Build Coastguard Worker   // are not needed (and would be undesirable in a signal handler) when reading
554*795d594fSAndroid Build Coastguard Worker   // a chain of constant references to get to a non-movable `Class.class` object.
555*795d594fSAndroid Build Coastguard Worker 
556*795d594fSAndroid Build Coastguard Worker   // Note: Allowing nested faults. Checking that the method is in one of the
557*795d594fSAndroid Build Coastguard Worker   // `LinearAlloc` spaces, or that objects we look at are in the `Heap` would be
558*795d594fSAndroid Build Coastguard Worker   // slow and require locking a mutex, which is undesirable in a signal handler.
559*795d594fSAndroid Build Coastguard Worker   // (Though we could register valid ranges similarly to the generated code ranges.)
560*795d594fSAndroid Build Coastguard Worker 
561*795d594fSAndroid Build Coastguard Worker   mirror::Object* klass =
562*795d594fSAndroid Build Coastguard Worker       method->GetDeclaringClassAddressWithoutBarrier()->AsMirrorPtr();
563*795d594fSAndroid Build Coastguard Worker   if (klass == nullptr || !IsAligned<kObjectAlignment>(klass)) {
564*795d594fSAndroid Build Coastguard Worker     VLOG(signals) << ((klass == nullptr) ? "null class" : "unaligned class");
565*795d594fSAndroid Build Coastguard Worker     return false;
566*795d594fSAndroid Build Coastguard Worker   }
567*795d594fSAndroid Build Coastguard Worker 
568*795d594fSAndroid Build Coastguard Worker   mirror::Class* class_class = klass->GetClass<kVerifyNone, kWithoutReadBarrier>();
569*795d594fSAndroid Build Coastguard Worker   if (class_class == nullptr || !IsAligned<kObjectAlignment>(class_class)) {
570*795d594fSAndroid Build Coastguard Worker     VLOG(signals) << ((klass == nullptr) ? "null class_class" : "unaligned class_class");
571*795d594fSAndroid Build Coastguard Worker     return false;
572*795d594fSAndroid Build Coastguard Worker   }
573*795d594fSAndroid Build Coastguard Worker 
574*795d594fSAndroid Build Coastguard Worker   if (class_class != class_class->GetClass<kVerifyNone, kWithoutReadBarrier>()) {
575*795d594fSAndroid Build Coastguard Worker     VLOG(signals) << "invalid class_class";
576*795d594fSAndroid Build Coastguard Worker     return false;
577*795d594fSAndroid Build Coastguard Worker   }
578*795d594fSAndroid Build Coastguard Worker 
579*795d594fSAndroid Build Coastguard Worker   return true;
580*795d594fSAndroid Build Coastguard Worker }
581*795d594fSAndroid Build Coastguard Worker 
IsValidReturnPc(ArtMethod ** sp,uintptr_t return_pc)582*795d594fSAndroid Build Coastguard Worker bool NullPointerHandler::IsValidReturnPc(ArtMethod** sp, uintptr_t return_pc) {
583*795d594fSAndroid Build Coastguard Worker   // Check if we can associate a dex PC with the return PC, whether from Nterp,
584*795d594fSAndroid Build Coastguard Worker   // or with an existing stack map entry for a compiled method.
585*795d594fSAndroid Build Coastguard Worker   // Note: Allowing nested faults if `IsValidMethod()` returned a false positive.
586*795d594fSAndroid Build Coastguard Worker   // Note: The `ArtMethod::GetOatQuickMethodHeader()` can acquire locks (at least
587*795d594fSAndroid Build Coastguard Worker   // `Locks::jit_lock_`) and if the thread already held such a lock, the signal
588*795d594fSAndroid Build Coastguard Worker   // handler would deadlock. However, if a thread is holding one of the locks
589*795d594fSAndroid Build Coastguard Worker   // below the mutator lock, the PC should be somewhere in ART code and should
590*795d594fSAndroid Build Coastguard Worker   // not match any registered generated code range, so such as a deadlock is
591*795d594fSAndroid Build Coastguard Worker   // unlikely. If it happens anyway, the worst case is that an internal ART crash
592*795d594fSAndroid Build Coastguard Worker   // would be reported as ANR.
593*795d594fSAndroid Build Coastguard Worker   ArtMethod* method = *sp;
594*795d594fSAndroid Build Coastguard Worker   const OatQuickMethodHeader* method_header = method->GetOatQuickMethodHeader(return_pc);
595*795d594fSAndroid Build Coastguard Worker   if (method_header == nullptr) {
596*795d594fSAndroid Build Coastguard Worker     VLOG(signals) << "No method header.";
597*795d594fSAndroid Build Coastguard Worker     return false;
598*795d594fSAndroid Build Coastguard Worker   }
599*795d594fSAndroid Build Coastguard Worker   VLOG(signals) << "looking for dex pc for return pc 0x" << std::hex << return_pc
600*795d594fSAndroid Build Coastguard Worker                 << " pc offset: 0x" << std::hex
601*795d594fSAndroid Build Coastguard Worker                 << (return_pc - reinterpret_cast<uintptr_t>(method_header->GetEntryPoint()));
602*795d594fSAndroid Build Coastguard Worker   uint32_t dexpc = method_header->ToDexPc(reinterpret_cast<ArtMethod**>(sp), return_pc, false);
603*795d594fSAndroid Build Coastguard Worker   VLOG(signals) << "dexpc: " << dexpc;
604*795d594fSAndroid Build Coastguard Worker   return dexpc != dex::kDexNoIndex;
605*795d594fSAndroid Build Coastguard Worker }
606*795d594fSAndroid Build Coastguard Worker 
607*795d594fSAndroid Build Coastguard Worker //
608*795d594fSAndroid Build Coastguard Worker // Suspension fault handler
609*795d594fSAndroid Build Coastguard Worker //
SuspensionHandler(FaultManager * manager)610*795d594fSAndroid Build Coastguard Worker SuspensionHandler::SuspensionHandler(FaultManager* manager) : FaultHandler(manager) {
611*795d594fSAndroid Build Coastguard Worker   manager_->AddHandler(this, true);
612*795d594fSAndroid Build Coastguard Worker }
613*795d594fSAndroid Build Coastguard Worker 
614*795d594fSAndroid Build Coastguard Worker //
615*795d594fSAndroid Build Coastguard Worker // Stack overflow fault handler
616*795d594fSAndroid Build Coastguard Worker //
StackOverflowHandler(FaultManager * manager)617*795d594fSAndroid Build Coastguard Worker StackOverflowHandler::StackOverflowHandler(FaultManager* manager) : FaultHandler(manager) {
618*795d594fSAndroid Build Coastguard Worker   manager_->AddHandler(this, true);
619*795d594fSAndroid Build Coastguard Worker }
620*795d594fSAndroid Build Coastguard Worker 
621*795d594fSAndroid Build Coastguard Worker //
622*795d594fSAndroid Build Coastguard Worker // Stack trace handler, used to help get a stack trace from SIGSEGV inside of compiled code.
623*795d594fSAndroid Build Coastguard Worker //
JavaStackTraceHandler(FaultManager * manager)624*795d594fSAndroid Build Coastguard Worker JavaStackTraceHandler::JavaStackTraceHandler(FaultManager* manager) : FaultHandler(manager) {
625*795d594fSAndroid Build Coastguard Worker   manager_->AddHandler(this, false);
626*795d594fSAndroid Build Coastguard Worker }
627*795d594fSAndroid Build Coastguard Worker 
Action(int sig,siginfo_t * siginfo,void * context)628*795d594fSAndroid Build Coastguard Worker bool JavaStackTraceHandler::Action([[maybe_unused]] int sig, siginfo_t* siginfo, void* context) {
629*795d594fSAndroid Build Coastguard Worker   // Make sure that we are in the generated code, but we may not have a dex pc.
630*795d594fSAndroid Build Coastguard Worker   bool in_generated_code = manager_->IsInGeneratedCode(siginfo, context);
631*795d594fSAndroid Build Coastguard Worker   if (in_generated_code) {
632*795d594fSAndroid Build Coastguard Worker     LOG(ERROR) << "Dumping java stack trace for crash in generated code";
633*795d594fSAndroid Build Coastguard Worker     Thread* self = Thread::Current();
634*795d594fSAndroid Build Coastguard Worker 
635*795d594fSAndroid Build Coastguard Worker     uintptr_t sp = FaultManager::GetFaultSp(context);
636*795d594fSAndroid Build Coastguard Worker     CHECK_NE(sp, 0u);  // Otherwise we should not have reached this handler.
637*795d594fSAndroid Build Coastguard Worker     // Inside of generated code, sp[0] is the method, so sp is the frame.
638*795d594fSAndroid Build Coastguard Worker     self->SetTopOfStack(reinterpret_cast<ArtMethod**>(sp));
639*795d594fSAndroid Build Coastguard Worker     self->DumpJavaStack(LOG_STREAM(ERROR));
640*795d594fSAndroid Build Coastguard Worker   }
641*795d594fSAndroid Build Coastguard Worker 
642*795d594fSAndroid Build Coastguard Worker   return false;  // Return false since we want to propagate the fault to the main signal handler.
643*795d594fSAndroid Build Coastguard Worker }
644*795d594fSAndroid Build Coastguard Worker 
645*795d594fSAndroid Build Coastguard Worker }   // namespace art
646