From c5f46b2f4b43e331650b32cb9d286246cd4fdac1 Mon Sep 17 00:00:00 2001 From: "ted.mielczarek" Date: Tue, 14 Oct 2008 11:21:34 +0000 Subject: Issue 276 - generate GUIDs ahead of time in Linux handler. r=Liu Li git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@290 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/client/linux/handler/exception_handler.cc | 64 ++++++++++++++++----------- src/client/linux/handler/exception_handler.h | 20 ++++++++- 2 files changed, 55 insertions(+), 29 deletions(-) (limited to 'src/client') diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc index b87acf4d..b253cb39 100644 --- a/src/client/linux/handler/exception_handler.cc +++ b/src/client/linux/handler/exception_handler.cc @@ -118,7 +118,9 @@ ExceptionHandler::~ExceptionHandler() { } bool ExceptionHandler::WriteMinidump() { - return InternalWriteMinidump(0, 0, NULL); + bool success = InternalWriteMinidump(0, 0, NULL); + UpdateNextID(); + return success; } // static @@ -226,41 +228,49 @@ bool ExceptionHandler::InternalWriteMinidump(int signo, if (filter_ && !filter_(callback_context_)) return false; + bool success = false; + // Block all the signals we want to process when writting minidump. + // We don't want it to be interrupted. + sigset_t sig_blocked, sig_old; + bool blocked = true; + sigfillset(&sig_blocked); + for (size_t i = 0; i < sizeof(SigTable) / sizeof(SigTable[0]); ++i) + sigdelset(&sig_blocked, SigTable[i]); + if (sigprocmask(SIG_BLOCK, &sig_blocked, &sig_old) != 0) { + blocked = false; + fprintf(stderr, "google_breakpad::ExceptionHandler::HandleException: " + "failed to block signals.\n"); + } + + success = minidump_generator_.WriteMinidumpToFile( + next_minidump_path_c_, signo, sighandler_ebp, sig_ctx); + + // Unblock the signals. + if (blocked) { + sigprocmask(SIG_SETMASK, &sig_old, &sig_old); + } + + if (callback_) + success = callback_(dump_path_c_, next_minidump_id_c_, + callback_context_, success); + return success; +} + +void ExceptionHandler::UpdateNextID() { GUID guid; - bool success = false;; char guid_str[kGUIDStringLength + 1]; if (CreateGUID(&guid) && GUIDToString(&guid, guid_str, sizeof(guid_str))) { + next_minidump_id_ = guid_str; + next_minidump_id_c_ = next_minidump_id_.c_str(); + char minidump_path[PATH_MAX]; snprintf(minidump_path, sizeof(minidump_path), "%s/%s.dmp", dump_path_c_, guid_str); - // Block all the signals we want to process when writting minidump. - // We don't want it to be interrupted. - sigset_t sig_blocked, sig_old; - bool blocked = true; - sigfillset(&sig_blocked); - for (size_t i = 0; i < sizeof(SigTable) / sizeof(SigTable[0]); ++i) - sigdelset(&sig_blocked, SigTable[i]); - if (sigprocmask(SIG_BLOCK, &sig_blocked, &sig_old) != 0) { - blocked = false; - fprintf(stderr, "google_breakpad::ExceptionHandler::HandleException: " - "failed to block signals.\n"); - } - - success = minidump_generator_.WriteMinidumpToFile( - minidump_path, signo, sighandler_ebp, sig_ctx); - - // Unblock the signals. - if (blocked) { - sigprocmask(SIG_SETMASK, &sig_old, &sig_old); - } - - if (callback_) - success = callback_(dump_path_c_, guid_str, - callback_context_, success); + next_minidump_path_ = minidump_path; + next_minidump_path_c_ = next_minidump_path_.c_str(); } - return success; } } // namespace google_breakpad diff --git a/src/client/linux/handler/exception_handler.h b/src/client/linux/handler/exception_handler.h index 2a212315..6e6156c5 100644 --- a/src/client/linux/handler/exception_handler.h +++ b/src/client/linux/handler/exception_handler.h @@ -126,6 +126,7 @@ class ExceptionHandler { void set_dump_path(const string &dump_path) { dump_path_ = dump_path; dump_path_c_ = dump_path_.c_str(); + UpdateNextID(); } // Writes a minidump immediately. This can be used to capture the @@ -160,6 +161,10 @@ class ExceptionHandler { bool InternalWriteMinidump(int signo, uintptr_t sighandler_ebp, struct sigcontext **sig_ctx); + // 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(); + private: FilterCallback filter_; MinidumpCallback callback_; @@ -168,9 +173,20 @@ class ExceptionHandler { // The directory in which a minidump will be written, set by the dump_path // argument to the constructor, or set_dump_path. string dump_path_; - // C style dump path. Keep this when setting dump path, since calling - // c_str() of std::string when crashing may not be safe. + + // The basename of the next minidump to be written, without the extension + string next_minidump_id_; + + // The full pathname of the next minidump to be written, including the file + // extension + string next_minidump_path_; + + // Pointers to C-string representations of the above. These are set + // when the above are set so we can avoid calling c_str during + // an exception. const char *dump_path_c_; + const char *next_minidump_id_c_; + const char *next_minidump_path_c_; // True if the ExceptionHandler installed an unhandled exception filter // when created (with an install_handler parameter set to true). -- cgit v1.2.1