diff options
author | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-02 21:28:50 +0000 |
---|---|---|
committer | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-02 21:28:50 +0000 |
commit | 8137f3170df7543e5213c051443f3157d168d859 (patch) | |
tree | 30bfc178eff4729854efba9f8e3093f30946f9c6 /chrome/browser/crash_handler_host_linux.cc | |
parent | d03c658c4baabe124e5eb3e540f13da296d64d8a (diff) | |
download | chromium_src-8137f3170df7543e5213c051443f3157d168d859.zip chromium_src-8137f3170df7543e5213c051443f3157d168d859.tar.gz chromium_src-8137f3170df7543e5213c051443f3157d168d859.tar.bz2 |
Linux: Handle renderer and plugin crashes on a separate thread.
Also set retries / timeouts for wget to attempt to limit the duration of each crash handler. Move some code out of headers while we're at it.
BUG=54071
TEST=change /usr/bin/wget to sleep forever, visit about:crash in a Breakpad-enabled build, make sure other renderers continue to work.
Review URL: http://codereview.chromium.org/3308007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58403 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 | 107 |
1 files changed, 84 insertions, 23 deletions
diff --git a/chrome/browser/crash_handler_host_linux.cc b/chrome/browser/crash_handler_host_linux.cc index e46c60d..06ceb96 100644 --- a/chrome/browser/crash_handler_host_linux.cc +++ b/chrome/browser/crash_handler_host_linux.cc @@ -20,6 +20,8 @@ #include "base/path_service.h" #include "base/rand_util.h" #include "base/string_util.h" +#include "base/task.h" +#include "base/thread.h" #include "breakpad/src/client/linux/handler/exception_handler.h" #include "breakpad/src/client/linux/minidump_writer/linux_dumper.h" #include "breakpad/src/client/linux/minidump_writer/minidump_writer.h" @@ -30,14 +32,27 @@ using google_breakpad::ExceptionHandler; +namespace { + +// Handles the crash dump and frees the allocated BreakpadInfo struct. +void CrashDumpTask(BreakpadInfo* info) { + HandleCrashDump(*info); + delete[] info->filename; + delete[] info->process_type; + delete[] info->crash_url; + delete[] info->guid; + delete[] info->distro; + delete info; +} + +} // namespace + // Since classes derived from CrashHandlerHostLinux are singletons, it's only // destroyed at the end of the processes lifetime, which is greater in span than // the lifetime of the IO message loop. DISABLE_RUNNABLE_METHOD_REFCOUNT(CrashHandlerHostLinux); -CrashHandlerHostLinux::CrashHandlerHostLinux() - : process_socket_(-1), - browser_socket_(-1) { +CrashHandlerHostLinux::CrashHandlerHostLinux() { int fds[2]; // We use SOCK_SEQPACKET rather than SOCK_DGRAM to prevent the process from // sending datagrams to other sockets on the system. The sandbox may prevent @@ -62,9 +77,17 @@ CrashHandlerHostLinux::CrashHandlerHostLinux() CrashHandlerHostLinux::~CrashHandlerHostLinux() { HANDLE_EINTR(close(process_socket_)); HANDLE_EINTR(close(browser_socket_)); + + // If we are quitting and there are crash dumps in the queue, discard them. + uploader_thread_->message_loop()->QuitNow(); } void CrashHandlerHostLinux::Init() { + SetProcessType(); + uploader_thread_.reset( + new base::Thread(std::string(process_type_ + "_crash_uploader").c_str())); + uploader_thread_->Start(); + MessageLoopForIO* ml = MessageLoopForIO::current(); CHECK(ml->WatchFileDescriptor( browser_socket_, true /* persistent */, @@ -95,24 +118,26 @@ void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) { struct msghdr msg = {0}; struct iovec iov[6]; char crash_context[kCrashContextSize]; - char guid[kGuidSize + 1]; - char crash_url[kMaxActiveURLSize + 1]; - char distro[kDistroSize + 1]; + char* guid = new char[kGuidSize + 1]; + char* crash_url = new char[kMaxActiveURLSize + 1]; + char* distro = new char[kDistroSize + 1]; char* tid_buf_addr = NULL; int tid_fd = -1; char control[kControlMsgSize]; - const ssize_t expected_msg_size = sizeof(crash_context) + sizeof(guid) + - sizeof(crash_url) + sizeof(distro) + + const ssize_t expected_msg_size = sizeof(crash_context) + + kGuidSize + 1 + + kMaxActiveURLSize + 1 + + kDistroSize + 1 + sizeof(tid_buf_addr) + sizeof(tid_fd); iov[0].iov_base = crash_context; iov[0].iov_len = sizeof(crash_context); iov[1].iov_base = guid; - iov[1].iov_len = sizeof(guid); + iov[1].iov_len = kGuidSize + 1; iov[2].iov_base = crash_url; - iov[2].iov_len = sizeof(crash_url); + iov[2].iov_len = kMaxActiveURLSize + 1; iov[3].iov_base = distro; - iov[3].iov_len = sizeof(distro); + iov[3].iov_len = kDistroSize + 1; iov[4].iov_base = &tid_buf_addr; iov[4].iov_len = sizeof(tid_buf_addr); iov[5].iov_base = &tid_fd; @@ -247,6 +272,7 @@ void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) { bool upload = true; FilePath dumps_path("/tmp"); + PathService::Get(base::DIR_TEMP, &dumps_path); if (getenv(env_vars::kHeadless)) { upload = false; PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path); @@ -276,20 +302,55 @@ void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) { // Sanitize the string data a bit more guid[kGuidSize] = crash_url[kMaxActiveURLSize] = distro[kDistroSize] = 0; - BreakpadInfo info; - info.filename = minidump_filename.c_str(); - info.process_type = process_type_.c_str(); - info.process_type_length = process_type_.length(); - info.crash_url = crash_url; - info.crash_url_length = strlen(crash_url); - info.guid = guid; - info.guid_length = strlen(guid); - info.distro = distro; - info.distro_length = strlen(distro); - info.upload = upload; - HandleCrashDump(info); + 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; + + uploader_thread_->message_loop()->PostTask( + FROM_HERE, + NewRunnableFunction(&CrashDumpTask, info)); } void CrashHandlerHostLinux::WillDestroyCurrentMessageLoop() { file_descriptor_watcher_.StopWatchingFileDescriptor(); } + +PluginCrashHandlerHostLinux::PluginCrashHandlerHostLinux() { +} + +PluginCrashHandlerHostLinux::~PluginCrashHandlerHostLinux() { +} + +void PluginCrashHandlerHostLinux::SetProcessType() { + process_type_ = "plugin"; +} + +RendererCrashHandlerHostLinux::RendererCrashHandlerHostLinux() { +} + +RendererCrashHandlerHostLinux::~RendererCrashHandlerHostLinux() { +} + +void RendererCrashHandlerHostLinux::SetProcessType() { + process_type_ = "renderer"; +} |