/thirdparty/breakpad/client/mac/handler/exception_handler.h

http://github.com/tomahawk-player/tomahawk · C Header · 277 lines · 110 code · 52 blank · 115 comment · 1 complexity · d45b8218b89dcb524326f161cb39df74 MD5 · raw file

  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. // exception_handler.h: MacOS exception handler
  30. // This class can install a Mach exception port handler to trap most common
  31. // programming errors. If an exception occurs, a minidump file will be
  32. // generated which contains detailed information about the process and the
  33. // exception.
  34. #ifndef CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__
  35. #define CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__
  36. #include <mach/mach.h>
  37. #include <TargetConditionals.h>
  38. #include <string>
  39. #include "processor/scoped_ptr.h"
  40. #if !TARGET_OS_IPHONE
  41. #include "client/mac/crash_generation/crash_generation_client.h"
  42. #endif
  43. namespace google_breakpad {
  44. using std::string;
  45. struct ExceptionParameters;
  46. enum HandlerThreadMessage {
  47. // Message ID telling the handler thread to write a dump.
  48. kWriteDumpMessage = 0,
  49. // Message ID telling the handler thread to write a dump and include
  50. // an exception stream.
  51. kWriteDumpWithExceptionMessage = 1,
  52. // Message ID telling the handler thread to quit.
  53. kShutdownMessage = 2
  54. };
  55. class ExceptionHandler {
  56. public:
  57. // A callback function to run before Breakpad performs any substantial
  58. // processing of an exception. A FilterCallback is called before writing
  59. // a minidump. context is the parameter supplied by the user as
  60. // callback_context when the handler was created.
  61. //
  62. // If a FilterCallback returns true, Breakpad will continue processing,
  63. // attempting to write a minidump. If a FilterCallback returns false, Breakpad
  64. // will immediately report the exception as unhandled without writing a
  65. // minidump, allowing another handler the opportunity to handle it.
  66. typedef bool (*FilterCallback)(void *context);
  67. // A callback function to run after the minidump has been written.
  68. // |minidump_id| is a unique id for the dump, so the minidump
  69. // file is <dump_dir>/<minidump_id>.dmp.
  70. // |context| is the value passed into the constructor.
  71. // |succeeded| indicates whether a minidump file was successfully written.
  72. // Return true if the exception was fully handled and breakpad should exit.
  73. // Return false to allow any other exception handlers to process the
  74. // exception.
  75. typedef bool (*MinidumpCallback)(const char *dump_dir,
  76. const char *minidump_id,
  77. void *context, bool succeeded);
  78. // A callback function which will be called directly if an exception occurs.
  79. // This bypasses the minidump file writing and simply gives the client
  80. // the exception information.
  81. typedef bool (*DirectCallback)( void *context,
  82. int exception_type,
  83. int exception_code,
  84. int exception_subcode,
  85. mach_port_t thread_name);
  86. // Creates a new ExceptionHandler instance to handle writing minidumps.
  87. // Minidump files will be written to dump_path, and the optional callback
  88. // is called after writing the dump file, as described above.
  89. // If install_handler is true, then a minidump will be written whenever
  90. // an unhandled exception occurs. If it is false, minidumps will only
  91. // be written when WriteMinidump is called.
  92. // If port_name is non-NULL, attempt to perform out-of-process dump generation
  93. // If port_name is NULL, in-process dump generation will be used.
  94. ExceptionHandler(const string &dump_path,
  95. FilterCallback filter, MinidumpCallback callback,
  96. void *callback_context, bool install_handler,
  97. const char *port_name);
  98. // A special constructor if we want to bypass minidump writing and
  99. // simply get a callback with the exception information.
  100. ExceptionHandler(DirectCallback callback,
  101. void *callback_context,
  102. bool install_handler);
  103. ~ExceptionHandler();
  104. // Get and set the minidump path.
  105. string dump_path() const { return dump_path_; }
  106. void set_dump_path(const string &dump_path) {
  107. dump_path_ = dump_path;
  108. dump_path_c_ = dump_path_.c_str();
  109. UpdateNextID(); // Necessary to put dump_path_ in next_minidump_path_.
  110. }
  111. // Writes a minidump immediately. This can be used to capture the
  112. // execution state independently of a crash. Returns true on success.
  113. bool WriteMinidump() {
  114. return WriteMinidump(false);
  115. }
  116. bool WriteMinidump(bool write_exception_stream);
  117. // Convenience form of WriteMinidump which does not require an
  118. // ExceptionHandler instance.
  119. static bool WriteMinidump(const string &dump_path, MinidumpCallback callback,
  120. void *callback_context) {
  121. return WriteMinidump(dump_path, false, callback, callback_context);
  122. }
  123. static bool WriteMinidump(const string &dump_path,
  124. bool write_exception_stream,
  125. MinidumpCallback callback,
  126. void *callback_context);
  127. // Write a minidump of child immediately. This can be used to capture
  128. // the execution state of a child process independently of a crash.
  129. static bool WriteMinidumpForChild(mach_port_t child,
  130. mach_port_t child_blamed_thread,
  131. const std::string &dump_path,
  132. MinidumpCallback callback,
  133. void *callback_context);
  134. // Returns whether out-of-process dump generation is used or not.
  135. bool IsOutOfProcess() const {
  136. #if TARGET_OS_IPHONE
  137. return false;
  138. #else
  139. return crash_generation_client_.get() != NULL;
  140. #endif
  141. }
  142. private:
  143. // Install the mach exception handler
  144. bool InstallHandler();
  145. // Uninstall the mach exception handler (if any)
  146. bool UninstallHandler(bool in_exception);
  147. // Setup the handler thread, and if |install_handler| is true, install the
  148. // mach exception port handler
  149. bool Setup(bool install_handler);
  150. // Uninstall the mach exception handler (if any) and terminate the helper
  151. // thread
  152. bool Teardown();
  153. // Send a mach message to the exception handler. Return true on
  154. // success, false otherwise.
  155. bool SendMessageToHandlerThread(HandlerThreadMessage message_id);
  156. // All minidump writing goes through this one routine
  157. bool WriteMinidumpWithException(int exception_type,
  158. int exception_code,
  159. int exception_subcode,
  160. mach_port_t thread_name,
  161. bool exit_after_write,
  162. bool report_current_thread);
  163. // When installed, this static function will be call from a newly created
  164. // pthread with |this| as the argument
  165. static void *WaitForMessage(void *exception_handler_class);
  166. // Signal handler for SIGABRT.
  167. static void SignalHandler(int sig, siginfo_t* info, void* uc);
  168. // disallow copy ctor and operator=
  169. explicit ExceptionHandler(const ExceptionHandler &);
  170. void operator=(const ExceptionHandler &);
  171. // Generates a new ID and stores it in next_minidump_id_, and stores the
  172. // path of the next minidump to be written in next_minidump_path_.
  173. void UpdateNextID();
  174. // These functions will suspend/resume all threads except for the
  175. // reporting thread
  176. bool SuspendThreads();
  177. bool ResumeThreads();
  178. // The destination directory for the minidump
  179. string dump_path_;
  180. // The basename of the next minidump w/o extension
  181. string next_minidump_id_;
  182. // The full path to the next minidump to be written, including extension
  183. string next_minidump_path_;
  184. // Pointers to the UTF-8 versions of above
  185. const char *dump_path_c_;
  186. const char *next_minidump_id_c_;
  187. const char *next_minidump_path_c_;
  188. // The callback function and pointer to be passed back after the minidump
  189. // has been written
  190. FilterCallback filter_;
  191. MinidumpCallback callback_;
  192. void *callback_context_;
  193. // The callback function to be passed back when we don't want a minidump
  194. // file to be written
  195. DirectCallback directCallback_;
  196. // The thread that is created for the handler
  197. pthread_t handler_thread_;
  198. // The port that is waiting on an exception message to be sent, if the
  199. // handler is installed
  200. mach_port_t handler_port_;
  201. // These variables save the previous exception handler's data so that it
  202. // can be re-installed when this handler is uninstalled
  203. ExceptionParameters *previous_;
  204. // True, if we've installed the exception handler
  205. bool installed_exception_handler_;
  206. // True, if we're in the process of uninstalling the exception handler and
  207. // the thread.
  208. bool is_in_teardown_;
  209. // Save the last result of the last minidump
  210. bool last_minidump_write_result_;
  211. // A mutex for use when writing out a minidump that was requested on a
  212. // thread other than the exception handler.
  213. pthread_mutex_t minidump_write_mutex_;
  214. // True, if we're using the mutext to indicate when mindump writing occurs
  215. bool use_minidump_write_mutex_;
  216. // Old signal handler for SIGABRT. Used to be able to restore it when
  217. // uninstalling.
  218. scoped_ptr<struct sigaction> old_handler_;
  219. #if !TARGET_OS_IPHONE
  220. // Client for out-of-process dump generation.
  221. scoped_ptr<CrashGenerationClient> crash_generation_client_;
  222. #endif
  223. };
  224. } // namespace google_breakpad
  225. #endif // CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__