From f480ba116971a56d4de25ae1df2369e3d5503d16 Mon Sep 17 00:00:00 2001 From: "ted.mielczarek" Date: Fri, 5 Feb 2010 18:21:31 +0000 Subject: Refactor Chrome's out-of-process Linux code into CrashGeneration{Server,Client} classes. Upstreamed from the Mozilla repository. Patch by Chris Jones r=me at https://bugzilla.mozilla.org/show_bug.cgi?id=516759 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@515 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/client/linux/handler/exception_handler.cc | 60 ++++++++++++++++------ src/client/linux/handler/exception_handler.h | 31 +++++++++-- .../linux/handler/exception_handler_unittest.cc | 11 +--- 3 files changed, 73 insertions(+), 29 deletions(-) (limited to 'src/client/linux/handler') diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc index a9e2fca2..7cb85473 100644 --- a/src/client/linux/handler/exception_handler.cc +++ b/src/client/linux/handler/exception_handler.cc @@ -114,23 +114,26 @@ ExceptionHandler::ExceptionHandler(const std::string &dump_path, MinidumpCallback callback, void *callback_context, bool install_handler) - : filter_(filter), - callback_(callback), - callback_context_(callback_context), - dump_path_(), - handler_installed_(install_handler), - crash_handler_(NULL) { - set_dump_path(dump_path); - - if (install_handler) { - InstallHandlers(); + : filter_(filter), + callback_(callback), + callback_context_(callback_context), + handler_installed_(install_handler) +{ + Init(dump_path, -1); +} - pthread_mutex_lock(&handler_stack_mutex_); - if (handler_stack_ == NULL) - handler_stack_ = new std::vector; - handler_stack_->push_back(this); - pthread_mutex_unlock(&handler_stack_mutex_); - } +ExceptionHandler::ExceptionHandler(const std::string &dump_path, + FilterCallback filter, + MinidumpCallback callback, + void* callback_context, + bool install_handler, + const int server_fd) + : filter_(filter), + callback_(callback), + callback_context_(callback_context), + handler_installed_(install_handler) +{ + Init(dump_path, server_fd); } // Runs before crashing: normal context. @@ -138,6 +141,28 @@ ExceptionHandler::~ExceptionHandler() { UninstallHandlers(); } +void ExceptionHandler::Init(const std::string &dump_path, + const int server_fd) +{ + crash_handler_ = NULL; + + if (0 <= server_fd) + crash_generation_client_ + .reset(CrashGenerationClient::TryCreate(server_fd)); + + if (handler_installed_) + InstallHandlers(); + + if (!IsOutOfProcess()) + set_dump_path(dump_path); + + pthread_mutex_lock(&handler_stack_mutex_); + if (handler_stack_ == NULL) + handler_stack_ = new std::vector; + handler_stack_->push_back(this); + pthread_mutex_unlock(&handler_stack_mutex_); +} + // Runs before crashing: normal context. bool ExceptionHandler::InstallHandlers() { // We run the signal handlers on an alternative stack because we might have @@ -280,6 +305,9 @@ bool ExceptionHandler::HandleSignal(int sig, siginfo_t* info, void* uc) { // This function may run in a compromised context: see the top of the file. bool ExceptionHandler::GenerateDump(CrashContext *context) { + if (IsOutOfProcess()) + return crash_generation_client_->RequestDump(context, sizeof(*context)); + static const unsigned kChildStackSize = 8000; PageAllocator allocator; uint8_t* stack = (uint8_t*) allocator.Alloc(kChildStackSize); diff --git a/src/client/linux/handler/exception_handler.h b/src/client/linux/handler/exception_handler.h index 34ce5e19..978bb010 100644 --- a/src/client/linux/handler/exception_handler.h +++ b/src/client/linux/handler/exception_handler.h @@ -35,6 +35,11 @@ #include +#include "client/linux/crash_generation/crash_generation_client.h" +#include "processor/scoped_ptr.h" + +struct sigaction; + namespace google_breakpad { // ExceptionHandler @@ -116,6 +121,18 @@ class ExceptionHandler { FilterCallback filter, MinidumpCallback callback, void *callback_context, bool install_handler); + + // Creates a new ExceptionHandler instance that can attempt to + // perform out-of-process dump generation if server_fd is valid. If + // server_fd is invalid, in-process dump generation will be + // used. See the above ctor for a description of the other + // parameters. + ExceptionHandler(const std::string& dump_path, + FilterCallback filter, MinidumpCallback callback, + void* callback_context, + bool install_handler, + const int server_fd); + ~ExceptionHandler(); // Get and set the minidump path. @@ -149,7 +166,14 @@ class ExceptionHandler { struct _libc_fpstate float_state; }; + // Returns whether out-of-process dump generation is used or not. + bool IsOutOfProcess() const { + return crash_generation_client_.get() != NULL; + } + private: + void Init(const std::string &dump_path, + const int server_fd); bool InstallHandlers(); void UninstallHandlers(); void PreresolveSymbols(); @@ -166,6 +190,8 @@ class ExceptionHandler { const MinidumpCallback callback_; void* const callback_context_; + scoped_ptr crash_generation_client_; + std::string dump_path_; std::string next_minidump_path_; std::string next_minidump_id_; @@ -189,9 +215,8 @@ class ExceptionHandler { static unsigned handler_stack_index_; static pthread_mutex_t handler_stack_mutex_; - // A vector of the old signal handlers. The void* is a pointer to a newly - // allocated sigaction structure to avoid pulling in too many includes. - std::vector > old_handlers_; + // A vector of the old signal handlers. + std::vector > old_handlers_; }; } // namespace google_breakpad diff --git a/src/client/linux/handler/exception_handler_unittest.cc b/src/client/linux/handler/exception_handler_unittest.cc index 2f4e1045..cf44b2f7 100644 --- a/src/client/linux/handler/exception_handler_unittest.cc +++ b/src/client/linux/handler/exception_handler_unittest.cc @@ -38,20 +38,11 @@ #include "client/linux/handler//exception_handler.h" #include "client/linux/minidump_writer/minidump_writer.h" +#include "common/linux/eintr_wrapper.h" #include "common/linux/linux_libc_support.h" #include "common/linux/linux_syscall_support.h" #include "breakpad_googletest_includes.h" -// This provides a wrapper around system calls which may be -// interrupted by a signal and return EINTR. See man 7 signal. -#define HANDLE_EINTR(x) ({ \ - typeof(x) __eintr_result__; \ - do { \ - __eintr_result__ = x; \ - } while (__eintr_result__ == -1 && errno == EINTR); \ - __eintr_result__;\ -}) - using namespace google_breakpad; static void sigchld_handler(int signo) { } -- cgit v1.2.1