diff options
author | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-17 23:01:57 +0000 |
---|---|---|
committer | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-17 23:01:57 +0000 |
commit | 154cbabdf3c6825228d08fcc5fa14cf7f734bce8 (patch) | |
tree | 67e38cd7009254b13a88a70f18229b0723482bc7 /chrome/browser/crash_handler_host_linux.cc | |
parent | d278196f3166b453a2788742189d2ac132282059 (diff) | |
download | chromium_src-154cbabdf3c6825228d08fcc5fa14cf7f734bce8.zip chromium_src-154cbabdf3c6825228d08fcc5fa14cf7f734bce8.tar.gz chromium_src-154cbabdf3c6825228d08fcc5fa14cf7f734bce8.tar.bz2 |
Breakpad Linux: Fix crash handler writing to disk on the wrong thread.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/6538033
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@75325 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/crash_handler_host_linux.cc')
-rw-r--r-- | chrome/browser/crash_handler_host_linux.cc | 108 |
1 files changed, 65 insertions, 43 deletions
diff --git a/chrome/browser/crash_handler_host_linux.cc b/chrome/browser/crash_handler_host_linux.cc index aa14cf5..fba536f 100644 --- a/chrome/browser/crash_handler_host_linux.cc +++ b/chrome/browser/crash_handler_host_linux.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,7 +8,6 @@ #include <stdlib.h> #include <sys/socket.h> #include <sys/syscall.h> -#include <sys/types.h> #include <unistd.h> #include "base/eintr_wrapper.h" @@ -35,6 +34,12 @@ using google_breakpad::ExceptionHandler; namespace { +// The length of the control message: +const unsigned kControlMsgSize = + CMSG_SPACE(2*sizeof(int)) + CMSG_SPACE(sizeof(struct ucred)); +// The length of the regular payload: +const unsigned kCrashContextSize = sizeof(ExceptionHandler::CrashContext); + // Handles the crash dump and frees the allocated BreakpadInfo struct. void CrashDumpTask(CrashHandlerHostLinux* handler, BreakpadInfo* info) { if (handler->IsShuttingDown()) @@ -112,13 +117,6 @@ void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) { // for writing the minidump as well as a file descriptor and a credentials // block so that they can't lie about their pid. - // The length of the control message: - static const unsigned kControlMsgSize = - CMSG_SPACE(2*sizeof(int)) + CMSG_SPACE(sizeof(struct ucred)); - // The length of the regular payload: - static const unsigned kCrashContextSize = - sizeof(ExceptionHandler::CrashContext); - const size_t kIovSize = 7; struct msghdr msg = {0}; struct iovec iov[kIovSize]; @@ -279,13 +277,49 @@ void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) { bad_context->tid = crashing_tid; } - bool upload = true; + // Sanitize the string data a bit more + guid[kGuidSize] = crash_url[kMaxActiveURLSize] = distro[kDistroSize] = 0; + + BreakpadInfo* info = new BreakpadInfo; + + info->process_type_length = process_type_.length(); + char* process_type_str = new char[info->process_type_length + 1]; + process_type_.copy(process_type_str, info->process_type_length); + process_type_str[info->process_type_length] = '\0'; + info->process_type = process_type_str; + + info->crash_url_length = strlen(crash_url); + info->crash_url = crash_url; + + info->guid_length = strlen(guid); + info->guid = guid; + + info->distro_length = strlen(distro); + info->distro = distro; + + info->upload = (getenv(env_vars::kHeadless) == NULL); + info->process_start_time = uptime; + + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, + NewRunnableMethod(this, + &CrashHandlerHostLinux::WriteDumpFile, + info, + crashing_pid, + reinterpret_cast<char*>(&crash_context), + signal_fd)); +} + +void CrashHandlerHostLinux::WriteDumpFile(BreakpadInfo* info, + pid_t crashing_pid, + char* crash_context, + int signal_fd) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + FilePath dumps_path("/tmp"); PathService::Get(base::DIR_TEMP, &dumps_path); - if (getenv(env_vars::kHeadless)) { - upload = false; + if (!info->upload) PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path); - } const uint64 rand = base::RandUint64(); const std::string minidump_filename = StringPrintf("%s/chromium-%s-minidump-%016" PRIx64 ".dmp", @@ -294,11 +328,27 @@ void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) { crashing_pid, crash_context, kCrashContextSize)) { LOG(ERROR) << "Failed to write crash dump for pid " << crashing_pid; - HANDLE_EINTR(close(signal_fd)); } + char* minidump_filename_str = new char[minidump_filename.length() + 1]; + minidump_filename.copy(minidump_filename_str, minidump_filename.length()); + minidump_filename_str[minidump_filename.length()] = '\0'; + info->filename = minidump_filename_str; + + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(this, + &CrashHandlerHostLinux::QueueCrashDumpTask, + info, + signal_fd)); +} + +void CrashHandlerHostLinux::QueueCrashDumpTask(BreakpadInfo* info, + int signal_fd) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + // Send the done signal to the process: it can exit now. - memset(&msg, 0, sizeof(msg)); + struct msghdr msg = {0}; struct iovec done_iov; done_iov.iov_base = const_cast<char*>("\x42"); done_iov.iov_len = 1; @@ -308,34 +358,6 @@ void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) { HANDLE_EINTR(sendmsg(signal_fd, &msg, MSG_DONTWAIT | MSG_NOSIGNAL)); HANDLE_EINTR(close(signal_fd)); - // Sanitize the string data a bit more - guid[kGuidSize] = crash_url[kMaxActiveURLSize] = distro[kDistroSize] = 0; - - BreakpadInfo* info = new BreakpadInfo; - - char* minidump_filename_str = new char[minidump_filename.length() + 1]; - minidump_filename.copy(minidump_filename_str, minidump_filename.length()); - minidump_filename_str[minidump_filename.length()] = '\0'; - info->filename = minidump_filename_str; - - info->process_type_length = process_type_.length(); - char* process_type_str = new char[info->process_type_length + 1]; - process_type_.copy(process_type_str, info->process_type_length); - process_type_str[info->process_type_length] = '\0'; - info->process_type = process_type_str; - - info->crash_url_length = strlen(crash_url); - info->crash_url = crash_url; - - info->guid_length = strlen(guid); - info->guid = guid; - - info->distro_length = strlen(distro); - info->distro = distro; - - info->upload = upload; - info->process_start_time = uptime; - uploader_thread_->message_loop()->PostTask( FROM_HERE, NewRunnableFunction(&CrashDumpTask, this, info)); |