aboutsummaryrefslogtreecommitdiff
path: root/src/client/linux/handler/exception_handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/linux/handler/exception_handler.cc')
-rw-r--r--src/client/linux/handler/exception_handler.cc116
1 files changed, 47 insertions, 69 deletions
diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc
index f505ff33..73c3bdfb 100644
--- a/src/client/linux/handler/exception_handler.cc
+++ b/src/client/linux/handler/exception_handler.cc
@@ -93,7 +93,6 @@
#include "client/linux/log/log.h"
#include "client/linux/minidump_writer/linux_dumper.h"
#include "client/linux/minidump_writer/minidump_writer.h"
-#include "common/linux/guid_creator.h"
#include "common/linux/eintr_wrapper.h"
#include "third_party/lss/linux_syscall_support.h"
@@ -126,60 +125,39 @@ pthread_mutex_t ExceptionHandler::handler_stack_mutex_ =
PTHREAD_MUTEX_INITIALIZER;
// Runs before crashing: normal context.
-ExceptionHandler::ExceptionHandler(const string &dump_path,
- FilterCallback filter,
- MinidumpCallback callback,
- void *callback_context,
- bool install_handler)
- : filter_(filter),
- callback_(callback),
- callback_context_(callback_context),
- handler_installed_(install_handler)
-{
- Init(dump_path, -1);
-}
-
-ExceptionHandler::ExceptionHandler(const string &dump_path,
+ExceptionHandler::ExceptionHandler(const MinidumpDescriptor& descriptor,
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.
-ExceptionHandler::~ExceptionHandler() {
- UninstallHandlers();
-}
-
-void ExceptionHandler::Init(const 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_)
+ : filter_(filter),
+ callback_(callback),
+ callback_context_(callback_context),
+ minidump_descriptor_(descriptor),
+ crash_handler_(NULL) {
+ if (server_fd >= 0)
+ crash_generation_client_.reset(CrashGenerationClient::TryCreate(server_fd));
+
+ if (install_handler)
InstallHandlers();
- if (!IsOutOfProcess())
- set_dump_path(dump_path);
+ if (!IsOutOfProcess() && !minidump_descriptor_.IsFD())
+ minidump_descriptor_.UpdatePath();
pthread_mutex_lock(&handler_stack_mutex_);
- if (handler_stack_ == NULL)
- handler_stack_ = new std::vector<ExceptionHandler *>;
+ if (!handler_stack_)
+ handler_stack_ = new std::vector<ExceptionHandler*>;
handler_stack_->push_back(this);
pthread_mutex_unlock(&handler_stack_mutex_);
}
// Runs before crashing: normal context.
+ExceptionHandler::~ExceptionHandler() {
+ UninstallHandlers();
+}
+
+// Runs before crashing: normal context.
bool ExceptionHandler::InstallHandlers() {
// We run the signal handlers on an alternative stack because we might have
// crashed because of a stack overflow.
@@ -237,24 +215,6 @@ void ExceptionHandler::UninstallHandlers() {
old_handlers_.clear();
}
-// Runs before crashing: normal context.
-void ExceptionHandler::UpdateNextID() {
- GUID guid;
- 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);
-
- next_minidump_path_ = minidump_path;
- next_minidump_path_c_ = next_minidump_path_.c_str();
- }
-}
-
// void ExceptionHandler::set_crash_handler(HandlerCallback callback) {
// crash_handler_ = callback;
// }
@@ -308,6 +268,7 @@ void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) {
struct ThreadArgument {
pid_t pid; // the crashing process
+ const MinidumpDescriptor* minidump_descriptor;
ExceptionHandler* handler;
const void* context; // a CrashContext structure
size_t context_size;
@@ -378,6 +339,7 @@ bool ExceptionHandler::GenerateDump(CrashContext *context) {
ThreadArgument thread_arg;
thread_arg.handler = this;
+ thread_arg.minidump_descriptor = &minidump_descriptor_;
thread_arg.pid = getpid();
thread_arg.context = context;
thread_arg.context_size = sizeof(*context);
@@ -420,11 +382,8 @@ bool ExceptionHandler::GenerateDump(CrashContext *context) {
}
bool success = r != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0;
-
if (callback_)
- success = callback_(dump_path_c_, next_minidump_id_c_,
- callback_context_, success);
-
+ success = callback_(minidump_descriptor_, callback_context_, success);
return success;
}
@@ -461,7 +420,14 @@ void ExceptionHandler::WaitForContinueSignal() {
// Runs on the cloned process.
bool ExceptionHandler::DoDump(pid_t crashing_process, const void* context,
size_t context_size) {
- return google_breakpad::WriteMinidump(next_minidump_path_c_,
+ if (minidump_descriptor_.IsFD()) {
+ return google_breakpad::WriteMinidump(minidump_descriptor_.fd(),
+ crashing_process,
+ context,
+ context_size,
+ mapping_list_);
+ }
+ return google_breakpad::WriteMinidump(minidump_descriptor_.path(),
crashing_process,
context,
context_size,
@@ -469,15 +435,29 @@ bool ExceptionHandler::DoDump(pid_t crashing_process, const void* context,
}
// static
-bool ExceptionHandler::WriteMinidump(const string &dump_path,
+bool ExceptionHandler::WriteMinidump(const string& dump_path,
MinidumpCallback callback,
void* callback_context) {
- ExceptionHandler eh(dump_path, NULL, callback, callback_context, false);
+ MinidumpDescriptor descriptor(dump_path);
+ ExceptionHandler eh(descriptor, NULL, callback, callback_context, false, -1);
return eh.WriteMinidump();
}
bool ExceptionHandler::WriteMinidump() {
#if !defined(__ARM_EABI__)
+ if (!IsOutOfProcess() && !minidump_descriptor_.IsFD()) {
+ // Update the path of the minidump so that this can be called multiple times
+ // and new files are created for each minidump. This is done before the
+ // generation happens, as clients may want to access the MinidumpDescriptor
+ // after this call to find the exact path to the minidump file.
+ minidump_descriptor_.UpdatePath();
+ } else if (minidump_descriptor_.IsFD()) {
+ // Reposition the FD to its beginning and resize it to get rid of the
+ // previous minidump info.
+ lseek(minidump_descriptor_.fd(), 0, SEEK_SET);
+ ftruncate(minidump_descriptor_.fd(), 0);
+ }
+
// Allow ourselves to be dumped.
sys_prctl(PR_SET_DUMPABLE, 1);
@@ -489,9 +469,7 @@ bool ExceptionHandler::WriteMinidump() {
sizeof(context.float_state));
context.tid = sys_gettid();
- bool success = GenerateDump(&context);
- UpdateNextID();
- return success;
+ return GenerateDump(&context);
#else
return false;
#endif // !defined(__ARM_EABI__)