• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <signal.h>
22 #include <vector>
23 #include <setjmp.h>
24 #include <stdint.h>
25 
26 #include "base/mutex.h"   // For annotalysis.
27 
28 namespace art {
29 
30 namespace mirror {
31 class ArtMethod;
32 }  // namespace mirror
33 
34 class FaultHandler;
35 
36 class FaultManager {
37  public:
38   FaultManager();
39   ~FaultManager();
40 
41   void Init();
42   void Shutdown();
43   void EnsureArtActionInFrontOfSignalChain();
44 
45   void HandleFault(int sig, siginfo_t* info, void* context);
46   void HandleNestedSignal(int sig, siginfo_t* info, void* context);
47   void AddHandler(FaultHandler* handler, bool generated_code);
48   void RemoveHandler(FaultHandler* handler);
49 
50   // Note that the following two functions are called in the context of a signal handler.
51   // The IsInGeneratedCode() function checks that the mutator lock is held before it
52   // calls GetMethodAndReturnPCAndSP().
53   // TODO: think about adding lock assertions and fake lock and unlock functions.
54   void GetMethodAndReturnPcAndSp(siginfo_t* siginfo, void* context, mirror::ArtMethod** out_method,
55                                  uintptr_t* out_return_pc, uintptr_t* out_sp)
56                                  NO_THREAD_SAFETY_ANALYSIS;
57   bool IsInGeneratedCode(siginfo_t* siginfo, void *context, bool check_dex_pc)
58                          NO_THREAD_SAFETY_ANALYSIS;
59 
60  private:
61   std::vector<FaultHandler*> generated_code_handlers_;
62   std::vector<FaultHandler*> other_handlers_;
63   struct sigaction oldaction_;
64   bool initialized_;
65   DISALLOW_COPY_AND_ASSIGN(FaultManager);
66 };
67 
68 class FaultHandler {
69  public:
70   explicit FaultHandler(FaultManager* manager);
~FaultHandler()71   virtual ~FaultHandler() {}
GetFaultManager()72   FaultManager* GetFaultManager() {
73     return manager_;
74   }
75 
76   virtual bool Action(int sig, siginfo_t* siginfo, void* context) = 0;
77 
78  protected:
79   FaultManager* const manager_;
80 
81  private:
82   DISALLOW_COPY_AND_ASSIGN(FaultHandler);
83 };
84 
85 class NullPointerHandler FINAL : public FaultHandler {
86  public:
87   explicit NullPointerHandler(FaultManager* manager);
88 
89   bool Action(int sig, siginfo_t* siginfo, void* context) OVERRIDE;
90 
91  private:
92   DISALLOW_COPY_AND_ASSIGN(NullPointerHandler);
93 };
94 
95 class SuspensionHandler FINAL : public FaultHandler {
96  public:
97   explicit SuspensionHandler(FaultManager* manager);
98 
99   bool Action(int sig, siginfo_t* siginfo, void* context) OVERRIDE;
100 
101  private:
102   DISALLOW_COPY_AND_ASSIGN(SuspensionHandler);
103 };
104 
105 class StackOverflowHandler FINAL : public FaultHandler {
106  public:
107   explicit StackOverflowHandler(FaultManager* manager);
108 
109   bool Action(int sig, siginfo_t* siginfo, void* context) OVERRIDE;
110 
111  private:
112   DISALLOW_COPY_AND_ASSIGN(StackOverflowHandler);
113 };
114 
115 class JavaStackTraceHandler FINAL : public FaultHandler {
116  public:
117   explicit JavaStackTraceHandler(FaultManager* manager);
118 
119   bool Action(int sig, siginfo_t* siginfo, void* context) OVERRIDE NO_THREAD_SAFETY_ANALYSIS;
120 
121  private:
122   DISALLOW_COPY_AND_ASSIGN(JavaStackTraceHandler);
123 };
124 
125 // Statically allocated so the the signal handler can Get access to it.
126 extern FaultManager fault_manager;
127 
128 }       // namespace art
129 #endif  // ART_RUNTIME_FAULT_HANDLER_H_
130 
131