exception_handler.h revision de2fd15db9a480c807ba337690669538a97756a4
1// Copyright (c) 2006, Google Inc. 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: 7// 8// * Redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer. 10// * Redistributions in binary form must reproduce the above 11// copyright notice, this list of conditions and the following disclaimer 12// in the documentation and/or other materials provided with the 13// distribution. 14// * Neither the name of Google Inc. nor the names of its 15// contributors may be used to endorse or promote products derived from 16// this software without specific prior written permission. 17// 18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30// exception_handler.h: MacOS exception handler 31// This class can install a Mach exception port handler to trap most common 32// programming errors. If an exception occurs, a minidump file will be 33// generated which contains detailed information about the process and the 34// exception. 35 36#ifndef CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__ 37#define CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__ 38 39#include <mach/mach.h> 40 41#include <string> 42 43namespace google_breakpad { 44 45using std::string; 46 47struct ExceptionParameters; 48 49class ExceptionHandler { 50 public: 51 // A callback function to run before Breakpad performs any substantial 52 // processing of an exception. A FilterCallback is called before writing 53 // a minidump. context is the parameter supplied by the user as 54 // callback_context when the handler was created. 55 // 56 // If a FilterCallback returns true, Breakpad will continue processing, 57 // attempting to write a minidump. If a FilterCallback returns false, Breakpad 58 // will immediately report the exception as unhandled without writing a 59 // minidump, allowing another handler the opportunity to handle it. 60 typedef bool (*FilterCallback)(void *context); 61 62 // A callback function to run after the minidump has been written. 63 // |minidump_id| is a unique id for the dump, so the minidump 64 // file is <dump_dir>/<minidump_id>.dmp. 65 // |context| is the value passed into the constructor. 66 // |succeeded| indicates whether a minidump file was successfully written. 67 // Return true if the exception was fully handled and breakpad should exit. 68 // Return false to allow any other exception handlers to process the 69 // exception. 70 typedef bool (*MinidumpCallback)(const char *dump_dir, 71 const char *minidump_id, 72 void *context, bool succeeded); 73 74 // A callback function which will be called directly if an exception occurs. 75 // This bypasses the minidump file writing and simply gives the client 76 // the exception information. 77 typedef bool (*DirectCallback)( void *context, 78 int exception_type, 79 int exception_code, 80 mach_port_t thread_name); 81 82 // Creates a new ExceptionHandler instance to handle writing minidumps. 83 // Minidump files will be written to dump_path, and the optional callback 84 // is called after writing the dump file, as described above. 85 // If install_handler is true, then a minidump will be written whenever 86 // an unhandled exception occurs. If it is false, minidumps will only 87 // be written when WriteMinidump is called. 88 ExceptionHandler(const string &dump_path, 89 FilterCallback filter, MinidumpCallback callback, 90 void *callback_context, bool install_handler); 91 92 // A special constructor if we want to bypass minidump writing and 93 // simply get a callback with the exception information. 94 ExceptionHandler(DirectCallback callback, 95 void *callback_context, 96 bool install_handler); 97 98 ~ExceptionHandler(); 99 100 // Get and set the minidump path. 101 string dump_path() const { return dump_path_; } 102 void set_dump_path(const string &dump_path) { 103 dump_path_ = dump_path; 104 dump_path_c_ = dump_path_.c_str(); 105 UpdateNextID(); // Necessary to put dump_path_ in next_minidump_path_. 106 } 107 108 // Writes a minidump immediately. This can be used to capture the 109 // execution state independently of a crash. Returns true on success. 110 bool WriteMinidump(); 111 112 // Convenience form of WriteMinidump which does not require an 113 // ExceptionHandler instance. 114 static bool WriteMinidump(const string &dump_path, MinidumpCallback callback, 115 void *callback_context); 116 117 private: 118 // Install the mach exception handler 119 bool InstallHandler(); 120 121 // Uninstall the mach exception handler (if any) 122 bool UninstallHandler(bool in_exception); 123 124 // Setup the handler thread, and if |install_handler| is true, install the 125 // mach exception port handler 126 bool Setup(bool install_handler); 127 128 // Uninstall the mach exception handler (if any) and terminate the helper 129 // thread 130 bool Teardown(); 131 132 // Send an "empty" mach message to the exception handler. Return true on 133 // success, false otherwise 134 bool SendEmptyMachMessage(); 135 136 // All minidump writing goes through this one routine 137 bool WriteMinidumpWithException(int exception_type, int exception_code, 138 mach_port_t thread_name); 139 140 // When installed, this static function will be call from a newly created 141 // pthread with |this| as the argument 142 static void *WaitForMessage(void *exception_handler_class); 143 144 // disallow copy ctor and operator= 145 explicit ExceptionHandler(const ExceptionHandler &); 146 void operator=(const ExceptionHandler &); 147 148 // Generates a new ID and stores it in next_minidump_id_, and stores the 149 // path of the next minidump to be written in next_minidump_path_. 150 void UpdateNextID(); 151 152 // These functions will suspend/resume all threads except for the 153 // reporting thread 154 bool SuspendThreads(); 155 bool ResumeThreads(); 156 157 // The destination directory for the minidump 158 string dump_path_; 159 160 // The basename of the next minidump w/o extension 161 string next_minidump_id_; 162 163 // The full path to the next minidump to be written, including extension 164 string next_minidump_path_; 165 166 // Pointers to the UTF-8 versions of above 167 const char *dump_path_c_; 168 const char *next_minidump_id_c_; 169 const char *next_minidump_path_c_; 170 171 // The callback function and pointer to be passed back after the minidump 172 // has been written 173 FilterCallback filter_; 174 MinidumpCallback callback_; 175 void *callback_context_; 176 177 // The callback function to be passed back when we don't want a minidump 178 // file to be written 179 DirectCallback directCallback_; 180 181 // The thread that is created for the handler 182 pthread_t handler_thread_; 183 184 // The port that is waiting on an exception message to be sent, if the 185 // handler is installed 186 mach_port_t handler_port_; 187 188 // These variables save the previous exception handler's data so that it 189 // can be re-installed when this handler is uninstalled 190 ExceptionParameters *previous_; 191 192 // True, if we've installed the exception handler 193 bool installed_exception_handler_; 194 195 // True, if we're in the process of uninstalling the exception handler and 196 // the thread. 197 bool is_in_teardown_; 198 199 // Save the last result of the last minidump 200 bool last_minidump_write_result_; 201 202 // A mutex for use when writing out a minidump that was requested on a 203 // thread other than the exception handler. 204 pthread_mutex_t minidump_write_mutex_; 205 206 // True, if we're using the mutext to indicate when mindump writing occurs 207 bool use_minidump_write_mutex_; 208}; 209 210} // namespace google_breakpad 211 212#endif // CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__ 213