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