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 
     18 #ifndef ART_RUNTIME_FAULT_HANDLER_H_
     19 #define ART_RUNTIME_FAULT_HANDLER_H_
     20 
     21 #include <setjmp.h>
     22 #include <signal.h>
     23 #include <stdint.h>
     24 
     25 #include <vector>
     26 
     27 #include "base/mutex.h"  // For annotalysis.
     28 
     29 namespace art {
     30 
     31 class ArtMethod;
     32 class FaultHandler;
     33 
     34 class FaultManager {
     35  public:
     36   FaultManager();
     37   ~FaultManager();
     38 
     39   void Init();
     40 
     41   // Unclaim signals.
     42   void Release();
     43 
     44   // Unclaim signals and delete registered handlers.
     45   void Shutdown();
     46 
     47   // Try to handle a fault, returns true if successful.
     48   bool HandleFault(int sig, siginfo_t* info, void* context);
     49 
     50   // Added handlers are owned by the fault handler and will be freed on Shutdown().
     51   void AddHandler(FaultHandler* handler, bool generated_code);
     52   void RemoveHandler(FaultHandler* handler);
     53 
     54   // Note that the following two functions are called in the context of a signal handler.
     55   // The IsInGeneratedCode() function checks that the mutator lock is held before it
     56   // calls GetMethodAndReturnPCAndSP().
     57   // TODO: think about adding lock assertions and fake lock and unlock functions.
     58   void GetMethodAndReturnPcAndSp(siginfo_t* siginfo, void* context, ArtMethod** out_method,
     59                                  uintptr_t* out_return_pc, uintptr_t* out_sp)
     60                                  NO_THREAD_SAFETY_ANALYSIS;
     61   bool IsInGeneratedCode(siginfo_t* siginfo, void *context, bool check_dex_pc)
     62                          NO_THREAD_SAFETY_ANALYSIS;
     63 
     64  private:
     65   // The HandleFaultByOtherHandlers function is only called by HandleFault function for generated code.
     66   bool HandleFaultByOtherHandlers(int sig, siginfo_t* info, void* context)
     67                                   NO_THREAD_SAFETY_ANALYSIS;
     68 
     69   std::vector<FaultHandler*> generated_code_handlers_;
     70   std::vector<FaultHandler*> other_handlers_;
     71   struct sigaction oldaction_;
     72   bool initialized_;
     73   DISALLOW_COPY_AND_ASSIGN(FaultManager);
     74 };
     75 
     76 class FaultHandler {
     77  public:
     78   explicit FaultHandler(FaultManager* manager);
     79   virtual ~FaultHandler() {}
     80   FaultManager* GetFaultManager() {
     81     return manager_;
     82   }
     83 
     84   virtual bool Action(int sig, siginfo_t* siginfo, void* context) = 0;
     85 
     86  protected:
     87   FaultManager* const manager_;
     88 
     89  private:
     90   DISALLOW_COPY_AND_ASSIGN(FaultHandler);
     91 };
     92 
     93 class NullPointerHandler FINAL : public FaultHandler {
     94  public:
     95   explicit NullPointerHandler(FaultManager* manager);
     96 
     97   bool Action(int sig, siginfo_t* siginfo, void* context) OVERRIDE;
     98 
     99   static bool IsValidImplicitCheck(siginfo_t* siginfo) {
    100     // Our implicit NPE checks always limit the range to a page.
    101     // Note that the runtime will do more exhaustive checks (that we cannot
    102     // reasonably do in signal processing code) based on the dex instruction
    103     // faulting.
    104     return CanDoImplicitNullCheckOn(reinterpret_cast<uintptr_t>(siginfo->si_addr));
    105   }
    106 
    107  private:
    108   DISALLOW_COPY_AND_ASSIGN(NullPointerHandler);
    109 };
    110 
    111 class SuspensionHandler FINAL : public FaultHandler {
    112  public:
    113   explicit SuspensionHandler(FaultManager* manager);
    114 
    115   bool Action(int sig, siginfo_t* siginfo, void* context) OVERRIDE;
    116 
    117  private:
    118   DISALLOW_COPY_AND_ASSIGN(SuspensionHandler);
    119 };
    120 
    121 class StackOverflowHandler FINAL : public FaultHandler {
    122  public:
    123   explicit StackOverflowHandler(FaultManager* manager);
    124 
    125   bool Action(int sig, siginfo_t* siginfo, void* context) OVERRIDE;
    126 
    127  private:
    128   DISALLOW_COPY_AND_ASSIGN(StackOverflowHandler);
    129 };
    130 
    131 class JavaStackTraceHandler FINAL : public FaultHandler {
    132  public:
    133   explicit JavaStackTraceHandler(FaultManager* manager);
    134 
    135   bool Action(int sig, siginfo_t* siginfo, void* context) OVERRIDE NO_THREAD_SAFETY_ANALYSIS;
    136 
    137  private:
    138   DISALLOW_COPY_AND_ASSIGN(JavaStackTraceHandler);
    139 };
    140 
    141 // Statically allocated so the the signal handler can Get access to it.
    142 extern FaultManager fault_manager;
    143 
    144 }       // namespace art
    145 #endif  // ART_RUNTIME_FAULT_HANDLER_H_
    146 
    147