mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2025-12-30 19:24:45 +01:00
Add Mac exception handler and generator. Fixes issue #69. Reviewed by mmentovai.
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@98 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
c4d599912c
commit
5ac2b9a569
7 changed files with 2134 additions and 0 deletions
188
src/client/mac/handler/exception_handler.h
Normal file
188
src/client/mac/handler/exception_handler.h
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
// Copyright (c) 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// exception_handler.h: MacOS exception handler
|
||||
// This class can install a Mach exception port handler to trap most common
|
||||
// programming errors. If an exception occurs, a minidump file will be
|
||||
// generated which contains detailed information about the process and the
|
||||
// exception.
|
||||
|
||||
#ifndef CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__
|
||||
#define CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__
|
||||
|
||||
#include <mach/mach.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace google_airbag {
|
||||
|
||||
using std::string;
|
||||
|
||||
struct ExceptionParameters;
|
||||
|
||||
class ExceptionHandler {
|
||||
public:
|
||||
// A callback function to run before Airbag performs any substantial
|
||||
// processing of an exception. A FilterCallback is called before writing
|
||||
// a minidump. context is the parameter supplied by the user as
|
||||
// callback_context when the handler was created.
|
||||
//
|
||||
// If a FilterCallback returns true, Airbag will continue processing,
|
||||
// attempting to write a minidump. If a FilterCallback returns false, Airbag
|
||||
// will immediately report the exception as unhandled without writing a
|
||||
// minidump, allowing another handler the opportunity to handle it.
|
||||
typedef bool (*FilterCallback)(void *context);
|
||||
|
||||
// A callback function to run after the minidump has been written.
|
||||
// |minidump_id| is a unique id for the dump, so the minidump
|
||||
// file is <dump_dir>/<minidump_id>.dmp.
|
||||
// |context| is the value passed into the constructor.
|
||||
// |succeeded| indicates whether a minidump file was successfully written.
|
||||
// Return true if the exception was fully handled and airbag should exit.
|
||||
// Return false to allow any other exception handlers to process the
|
||||
// exception.
|
||||
typedef bool (*MinidumpCallback)(const char *dump_dir,
|
||||
const char *minidump_id,
|
||||
void *context, bool succeeded);
|
||||
|
||||
// Creates a new ExceptionHandler instance to handle writing minidumps.
|
||||
// Minidump files will be written to dump_path, and the optional callback
|
||||
// is called after writing the dump file, as described above.
|
||||
// If install_handler is true, then a minidump will be written whenever
|
||||
// an unhandled exception occurs. If it is false, minidumps will only
|
||||
// be written when WriteMinidump is called.
|
||||
ExceptionHandler(const string &dump_path,
|
||||
FilterCallback filter, MinidumpCallback callback,
|
||||
void *callback_context, bool install_handler);
|
||||
~ExceptionHandler();
|
||||
|
||||
// Get and set the minidump path.
|
||||
string dump_path() const { return dump_path_; }
|
||||
void set_dump_path(const string &dump_path) {
|
||||
dump_path_ = dump_path;
|
||||
dump_path_c_ = dump_path_.c_str();
|
||||
UpdateNextID(); // Necessary to put dump_path_ in next_minidump_path_.
|
||||
}
|
||||
|
||||
// Writes a minidump immediately. This can be used to capture the
|
||||
// execution state independently of a crash. Returns true on success.
|
||||
bool WriteMinidump();
|
||||
|
||||
// Convenience form of WriteMinidump which does not require an
|
||||
// ExceptionHandler instance.
|
||||
static bool WriteMinidump(const string &dump_path, MinidumpCallback callback,
|
||||
void *callback_context);
|
||||
|
||||
private:
|
||||
// Install the mach exception handler
|
||||
bool InstallHandler();
|
||||
|
||||
// Uninstall the mach exception handler (if any)
|
||||
bool UninstallHandler();
|
||||
|
||||
// Setup the handler thread, and if |install_handler| is true, install the
|
||||
// mach exception port handler
|
||||
bool Setup(bool install_handler);
|
||||
|
||||
// Uninstall the mach exception handler (if any) and terminate the helper
|
||||
// thread
|
||||
bool Teardown();
|
||||
|
||||
// Send an "empty" mach message to the exception handler. Return true on
|
||||
// success, false otherwise
|
||||
bool SendEmptyMachMessage();
|
||||
|
||||
// All minidump writing goes through this one routine
|
||||
bool WriteMinidumpWithException(int exception_type, int exception_code,
|
||||
mach_port_t thread_name);
|
||||
|
||||
// When installed, this static function will be call from a newly created
|
||||
// pthread with |this| as the argument
|
||||
static void *WaitForMessage(void *exception_handler_class);
|
||||
|
||||
// disallow copy ctor and operator=
|
||||
explicit ExceptionHandler(const ExceptionHandler &);
|
||||
void operator=(const ExceptionHandler &);
|
||||
|
||||
// Generates a new ID and stores it in next_minidump_id_, and stores the
|
||||
// path of the next minidump to be written in next_minidump_path_.
|
||||
void UpdateNextID();
|
||||
|
||||
// The destination directory for the minidump
|
||||
string dump_path_;
|
||||
|
||||
// The basename of the next minidump w/o extension
|
||||
string next_minidump_id_;
|
||||
|
||||
// The full path to the next minidump to be written, including extension
|
||||
string next_minidump_path_;
|
||||
|
||||
// Pointers to the UTF-8 versions of above
|
||||
const char *dump_path_c_;
|
||||
const char *next_minidump_id_c_;
|
||||
const char *next_minidump_path_c_;
|
||||
|
||||
// The callback function and pointer to be passed back after the minidump
|
||||
// has been written
|
||||
FilterCallback filter_;
|
||||
MinidumpCallback callback_;
|
||||
void *callback_context_;
|
||||
|
||||
// The thread that is created for the handler
|
||||
pthread_t handler_thread_;
|
||||
|
||||
// The port that is waiting on an exception message to be sent, if the
|
||||
// handler is installed
|
||||
mach_port_t handler_port_;
|
||||
|
||||
// These variables save the previous exception handler's data so that it
|
||||
// can be re-installed when this handler is uninstalled
|
||||
ExceptionParameters *previous_;
|
||||
|
||||
// True, if we've installed the exception handler
|
||||
bool installed_exception_handler_;
|
||||
|
||||
// True, if we're in the process of uninstalling the exception handler and
|
||||
// the thread.
|
||||
bool is_in_teardown_;
|
||||
|
||||
// Save the last result of the last minidump
|
||||
bool last_minidump_write_result_;
|
||||
|
||||
// A mutex for use when writing out a minidump that was requested on a
|
||||
// thread other than the exception handler.
|
||||
pthread_mutex_t minidump_write_mutex_;
|
||||
|
||||
// True, if we're using the mutext to indicate when mindump writing occurs
|
||||
bool use_minidump_write_mutex_;
|
||||
};
|
||||
|
||||
} // namespace google_airbag
|
||||
|
||||
#endif // CLIENT_MAC_HANDLER_EXCEPTION_HANDLER_H__
|
||||
Loading…
Add table
Add a link
Reference in a new issue