summaryrefslogtreecommitdiffstats
path: root/chrome/browser/crash_handler_host_linux.cc
diff options
context:
space:
mode:
authorthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-17 23:01:57 +0000
committerthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-17 23:01:57 +0000
commit154cbabdf3c6825228d08fcc5fa14cf7f734bce8 (patch)
tree67e38cd7009254b13a88a70f18229b0723482bc7 /chrome/browser/crash_handler_host_linux.cc
parentd278196f3166b453a2788742189d2ac132282059 (diff)
downloadchromium_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.cc108
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));