toolkit/crashreporter/google-breakpad/src/client/solaris/handler/exception_handler.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 // Copyright (c) 2007, Google Inc.
michael@0 2 // All rights reserved.
michael@0 3 //
michael@0 4 // Redistribution and use in source and binary forms, with or without
michael@0 5 // modification, are permitted provided that the following conditions are
michael@0 6 // met:
michael@0 7 //
michael@0 8 // * Redistributions of source code must retain the above copyright
michael@0 9 // notice, this list of conditions and the following disclaimer.
michael@0 10 // * Redistributions in binary form must reproduce the above
michael@0 11 // copyright notice, this list of conditions and the following disclaimer
michael@0 12 // in the documentation and/or other materials provided with the
michael@0 13 // distribution.
michael@0 14 // * Neither the name of Google Inc. nor the names of its
michael@0 15 // contributors may be used to endorse or promote products derived from
michael@0 16 // this software without specific prior written permission.
michael@0 17 //
michael@0 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
michael@0 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
michael@0 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@0 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@0 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
michael@0 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
michael@0 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
michael@0 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 29 //
michael@0 30 // Author: Alfred Peng
michael@0 31
michael@0 32 #ifndef CLIENT_SOLARIS_HANDLER_EXCEPTION_HANDLER_H__
michael@0 33 #define CLIENT_SOLARIS_HANDLER_EXCEPTION_HANDLER_H__
michael@0 34
michael@0 35 #include <map>
michael@0 36 #include <string>
michael@0 37 #include <vector>
michael@0 38
michael@0 39 #include "client/solaris/handler/minidump_generator.h"
michael@0 40
michael@0 41 namespace google_breakpad {
michael@0 42
michael@0 43 using std::string;
michael@0 44
michael@0 45 //
michael@0 46 // ExceptionHandler
michael@0 47 //
michael@0 48 // ExceptionHandler can write a minidump file when an exception occurs,
michael@0 49 // or when WriteMinidump() is called explicitly by your program.
michael@0 50 //
michael@0 51 // To have the exception handler write minidumps when an uncaught exception
michael@0 52 // (crash) occurs, you should create an instance early in the execution
michael@0 53 // of your program, and keep it around for the entire time you want to
michael@0 54 // have crash handling active (typically, until shutdown).
michael@0 55 // (NOTE): There should be only one this kind of exception handler
michael@0 56 // object per process.
michael@0 57 //
michael@0 58 // If you want to write minidumps without installing the exception handler,
michael@0 59 // you can create an ExceptionHandler with install_handler set to false,
michael@0 60 // then call WriteMinidump. You can also use this technique if you want to
michael@0 61 // use different minidump callbacks for different call sites.
michael@0 62 //
michael@0 63 // In either case, a callback function is called when a minidump is written,
michael@0 64 // which receives the unqiue id of the minidump. The caller can use this
michael@0 65 // id to collect and write additional application state, and to launch an
michael@0 66 // external crash-reporting application.
michael@0 67 //
michael@0 68 // Caller should try to make the callbacks as crash-friendly as possible,
michael@0 69 // it should avoid use heap memory allocation as much as possible.
michael@0 70 //
michael@0 71 class ExceptionHandler {
michael@0 72 public:
michael@0 73 // A callback function to run before Breakpad performs any substantial
michael@0 74 // processing of an exception. A FilterCallback is called before writing
michael@0 75 // a minidump. context is the parameter supplied by the user as
michael@0 76 // callback_context when the handler was created.
michael@0 77 //
michael@0 78 // If a FilterCallback returns true, Breakpad will continue processing,
michael@0 79 // attempting to write a minidump. If a FilterCallback returns false,
michael@0 80 // Breakpad will immediately report the exception as unhandled without
michael@0 81 // writing a minidump, allowing another handler the opportunity to handle it.
michael@0 82 typedef bool (*FilterCallback)(void *context);
michael@0 83
michael@0 84 // A callback function to run after the minidump has been written.
michael@0 85 // minidump_id is a unique id for the dump, so the minidump
michael@0 86 // file is <dump_path>/<minidump_id>.dmp. context is the parameter supplied
michael@0 87 // by the user as callback_context when the handler was created. succeeded
michael@0 88 // indicates whether a minidump file was successfully written.
michael@0 89 //
michael@0 90 // If an exception occurred and the callback returns true, Breakpad will
michael@0 91 // treat the exception as fully-handled, suppressing any other handlers from
michael@0 92 // being notified of the exception. If the callback returns false, Breakpad
michael@0 93 // will treat the exception as unhandled, and allow another handler to handle
michael@0 94 // it. If there are no other handlers, Breakpad will report the exception to
michael@0 95 // the system as unhandled, allowing a debugger or native crash dialog the
michael@0 96 // opportunity to handle the exception. Most callback implementations
michael@0 97 // should normally return the value of |succeeded|, or when they wish to
michael@0 98 // not report an exception of handled, false. Callbacks will rarely want to
michael@0 99 // return true directly (unless |succeeded| is true).
michael@0 100 typedef bool (*MinidumpCallback)(const char *dump_path,
michael@0 101 const char *minidump_id,
michael@0 102 void *context,
michael@0 103 bool succeeded);
michael@0 104
michael@0 105 // Creates a new ExceptionHandler instance to handle writing minidumps.
michael@0 106 // Before writing a minidump, the optional filter callback will be called.
michael@0 107 // Its return value determines whether or not Breakpad should write a
michael@0 108 // minidump. Minidump files will be written to dump_path, and the optional
michael@0 109 // callback is called after writing the dump file, as described above.
michael@0 110 // If install_handler is true, then a minidump will be written whenever
michael@0 111 // an unhandled exception occurs. If it is false, minidumps will only
michael@0 112 // be written when WriteMinidump is called.
michael@0 113 ExceptionHandler(const string &dump_path,
michael@0 114 FilterCallback filter, MinidumpCallback callback,
michael@0 115 void *callback_context,
michael@0 116 bool install_handler);
michael@0 117 ~ExceptionHandler();
michael@0 118
michael@0 119 // Get and Set the minidump path.
michael@0 120 string dump_path() const { return dump_path_; }
michael@0 121 void set_dump_path(const string &dump_path) {
michael@0 122 dump_path_ = dump_path;
michael@0 123 dump_path_c_ = dump_path_.c_str();
michael@0 124 }
michael@0 125
michael@0 126 // Writes a minidump immediately. This can be used to capture the
michael@0 127 // execution state independently of a crash. Returns true on success.
michael@0 128 bool WriteMinidump();
michael@0 129
michael@0 130 // Convenience form of WriteMinidump which does not require an
michael@0 131 // ExceptionHandler instance.
michael@0 132 static bool WriteMinidump(const string &dump_path,
michael@0 133 MinidumpCallback callback,
michael@0 134 void *callback_context);
michael@0 135
michael@0 136 private:
michael@0 137 // Setup crash handler.
michael@0 138 void SetupHandler();
michael@0 139 // Setup signal handler for a signal.
michael@0 140 void SetupHandler(int signo);
michael@0 141 // Teardown the handler for a signal.
michael@0 142 void TeardownHandler(int signo);
michael@0 143 // Teardown all handlers.
michael@0 144 void TeardownAllHandlers();
michael@0 145
michael@0 146 // Runs the main loop for the exception handler thread.
michael@0 147 static void* ExceptionHandlerThreadMain(void *lpParameter);
michael@0 148
michael@0 149 // Signal handler.
michael@0 150 static void HandleException(int signo);
michael@0 151
michael@0 152 // Write all the information to the dump file.
michael@0 153 // If called from a signal handler, sighandler_ebp is the ebp of
michael@0 154 // that signal handler's frame, and sig_ctx is an out parameter
michael@0 155 // that will be set to point at the ucontext_t that was placed
michael@0 156 // on the stack by the kernel. You can pass zero and NULL
michael@0 157 // for the second and third parameters if you are not calling
michael@0 158 // this from a signal handler.
michael@0 159 bool InternalWriteMinidump(int signo, uintptr_t sighandler_ebp,
michael@0 160 ucontext_t **sig_ctx);
michael@0 161
michael@0 162 private:
michael@0 163 // The callbacks before and after writing the dump file.
michael@0 164 FilterCallback filter_;
michael@0 165 MinidumpCallback callback_;
michael@0 166 void *callback_context_;
michael@0 167
michael@0 168 // The directory in which a minidump will be written, set by the dump_path
michael@0 169 // argument to the constructor, or set_dump_path.
michael@0 170 string dump_path_;
michael@0 171 // C style dump path. Keep this when setting dump path, since calling
michael@0 172 // c_str() of std::string when crashing may not be safe.
michael@0 173 const char *dump_path_c_;
michael@0 174
michael@0 175 // True if the ExceptionHandler installed an unhandled exception filter
michael@0 176 // when created (with an install_handler parameter set to true).
michael@0 177 bool installed_handler_;
michael@0 178
michael@0 179 // Keep the previous handlers for the signal.
michael@0 180 typedef void (*sighandler_t)(int);
michael@0 181 std::map<int, sighandler_t> old_handlers_;
michael@0 182
michael@0 183 // The global exception handler stack. This is need becuase there may exist
michael@0 184 // multiple ExceptionHandler instances in a process. Each will have itself
michael@0 185 // registered in this stack.
michael@0 186 static std::vector<ExceptionHandler *> *handler_stack_;
michael@0 187 // The index of the handler that should handle the next exception.
michael@0 188 static int handler_stack_index_;
michael@0 189 static pthread_mutex_t handler_stack_mutex_;
michael@0 190
michael@0 191 // The minidump generator.
michael@0 192 MinidumpGenerator minidump_generator_;
michael@0 193
michael@0 194 // disallow copy ctor and operator=
michael@0 195 explicit ExceptionHandler(const ExceptionHandler &);
michael@0 196 void operator=(const ExceptionHandler &);
michael@0 197 };
michael@0 198
michael@0 199 } // namespace google_breakpad
michael@0 200
michael@0 201 #endif // CLIENT_SOLARIS_HANDLER_EXCEPTION_HANDLER_H__

mercurial