xref: /aosp_15_r20/external/google-breakpad/src/client/ios/exception_handler_no_mach.h (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
1 // Copyright 2006 Google LLC
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are
5 // met:
6 //
7 //     * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 //     * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following disclaimer
11 // in the documentation and/or other materials provided with the
12 // distribution.
13 //     * Neither the name of Google LLC nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #ifndef CLIENT_IOS_HANDLER_EXCEPTION_HANDLER_NO_MACH_H__
30 #define CLIENT_IOS_HANDLER_EXCEPTION_HANDLER_NO_MACH_H__
31 
32 #include <mach/mach.h>
33 #include <TargetConditionals.h>
34 
35 #include <string>
36 
37 #include "client/mac/handler/ucontext_compat.h"
38 #include "common/scoped_ptr.h"
39 
40 namespace google_breakpad {
41 
42 using std::string;
43 
44 class ExceptionHandler {
45  public:
46   // A callback function to run before Breakpad performs any substantial
47   // processing of an exception.  A FilterCallback is called before writing
48   // a minidump.  context is the parameter supplied by the user as
49   // callback_context when the handler was created.
50   //
51   // If a FilterCallback returns true, Breakpad will continue processing,
52   // attempting to write a minidump.  If a FilterCallback returns false, Breakpad
53   // will immediately report the exception as unhandled without writing a
54   // minidump, allowing another handler the opportunity to handle it.
55   typedef bool (*FilterCallback)(void* context);
56 
57   // A callback function to run after the minidump has been written.
58   // |minidump_id| is a unique id for the dump, so the minidump
59   // file is <dump_dir>/<minidump_id>.dmp.
60   // |context| is the value passed into the constructor.
61   // |succeeded| indicates whether a minidump file was successfully written.
62   // Return true if the exception was fully handled and breakpad should exit.
63   // Return false to allow any other exception handlers to process the
64   // exception.
65   typedef bool (*MinidumpCallback)(const char* dump_dir,
66                                    const char* minidump_id,
67                                    void* context, bool succeeded);
68 
69   // A callback function which will be called directly if an exception occurs.
70   // This bypasses the minidump file writing and simply gives the client
71   // the exception information.
72   typedef bool (*DirectCallback)(void* context,
73                                  int exception_type,
74                                  int exception_code,
75                                  int exception_subcode,
76                                  mach_port_t thread_name);
77 
78   // Creates a new ExceptionHandler instance to handle writing minidumps.
79   // Minidump files will be written to dump_path, and the optional callback
80   // is called after writing the dump file, as described above.
81   // If install_handler is true, then a minidump will be written whenever
82   // an unhandled exception occurs.  If it is false, minidumps will only
83   // be written when WriteMinidump is called.
84   // If port_name is non-NULL, attempt to perform out-of-process dump generation
85   // If port_name is NULL, in-process dump generation will be used.
86   ExceptionHandler(const string& dump_path,
87                    FilterCallback filter, MinidumpCallback callback,
88                    void* callback_context, bool install_handler,
89                    const char* port_name);
90 
91   // A special constructor if we want to bypass minidump writing and
92   // simply get a callback with the exception information.
93   ExceptionHandler(DirectCallback callback,
94                    void* callback_context,
95                    bool install_handler);
96 
97   ~ExceptionHandler();
98 
99   // Get and set the minidump path.
dump_path()100   string dump_path() const { return dump_path_; }
set_dump_path(const string & dump_path)101   void set_dump_path(const string& dump_path) {
102     dump_path_ = dump_path;
103     dump_path_c_ = dump_path_.c_str();
104     UpdateNextID();  // Necessary to put dump_path_ in next_minidump_path_.
105   }
106 
107  private:
108   // Install the SIG exception handlers.
109   bool InstallHandlers();
110 
111   // Uninstall the SIG exception handlers.
112   bool UninstallHandlers();
113 
114   // Setup the handler thread, and if |install_handler| is true, install the
115   // mach exception port handler
116   bool Setup();
117 
118   // Uninstall the mach exception handler (if any) and terminate the helper
119   // thread
120   bool Teardown();
121 
122   // All minidump writing goes through this one routine.
123   // |task_context| can be NULL. If not, it will be used to retrieve the
124   // context of the current thread, instead of using |thread_get_state|.
125   bool WriteMinidumpWithException(int exception_type,
126                                   int exception_code,
127                                   int exception_subcode,
128                                   breakpad_ucontext_t* task_context,
129                                   mach_port_t thread_name,
130                                   bool exit_after_write,
131                                   bool report_current_thread);
132 
133   // Signal handler for SIG exceptions.
134   static void SignalHandler(int sig, siginfo_t* info, void* uc);
135 
136   // disallow copy ctor and operator=
137   explicit ExceptionHandler(const ExceptionHandler&);
138   void operator=(const ExceptionHandler&);
139 
140   // Generates a new ID and stores it in next_minidump_id_, and stores the
141   // path of the next minidump to be written in next_minidump_path_.
142   void UpdateNextID();
143 
144   // The destination directory for the minidump
145   string dump_path_;
146 
147   // The basename of the next minidump w/o extension
148   string next_minidump_id_;
149 
150   // The full path to the next minidump to be written, including extension
151   string next_minidump_path_;
152 
153   // Pointers to the UTF-8 versions of above
154   const char* dump_path_c_;
155   const char* next_minidump_id_c_;
156   const char* next_minidump_path_c_;
157 
158   // The callback function and pointer to be passed back after the minidump
159   // has been written
160   FilterCallback filter_;
161   MinidumpCallback callback_;
162   void* callback_context_;
163 
164   // The callback function to be passed back when we don't want a minidump
165   // file to be written
166   DirectCallback directCallback_;
167 
168   // True, if we've installed the exception handler
169   bool installed_exception_handler_;
170 
171   // True, if we're in the process of uninstalling the exception handler and
172   // the thread.
173   bool is_in_teardown_;
174 };
175 
176 }  // namespace google_breakpad
177 
178 #endif  // CLIENT_IOS_HANDLER_EXCEPTION_HANDLER_NO_MACH_H__
179