Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/crash_handler_host_linux.h" | 5 #include "chrome/browser/crash_handler_host_linux.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <stdlib.h> | 8 #include <stdlib.h> |
| 9 #include <sys/socket.h> | 9 #include <sys/socket.h> |
| 10 #include <sys/syscall.h> | 10 #include <sys/syscall.h> |
| 11 #include <unistd.h> | 11 #include <unistd.h> |
| 12 | 12 |
| 13 #include "base/bind.h" | 13 #include "base/bind.h" |
| 14 #include "base/bind_helpers.h" | 14 #include "base/bind_helpers.h" |
| 15 #include "base/files/file_path.h" | 15 #include "base/files/file_path.h" |
| 16 #include "base/format_macros.h" | 16 #include "base/format_macros.h" |
| 17 #include "base/linux_util.h" | 17 #include "base/linux_util.h" |
| 18 #include "base/logging.h" | 18 #include "base/logging.h" |
| 19 #include "base/memory/singleton.h" | 19 #include "base/memory/singleton.h" |
| 20 #include "base/message_loop.h" | 20 #include "base/message_loop.h" |
| 21 #include "base/path_service.h" | 21 #include "base/path_service.h" |
| 22 #include "base/posix/eintr_wrapper.h" | 22 #include "base/posix/eintr_wrapper.h" |
| 23 #include "base/rand_util.h" | 23 #include "base/rand_util.h" |
| 24 #include "base/string_util.h" | 24 #include "base/string_util.h" |
| 25 #include "base/stringprintf.h" | 25 #include "base/stringprintf.h" |
| 26 #include "base/threading/thread.h" | 26 #include "base/threading/thread.h" |
| 27 #include "breakpad/src/client/linux/handler/exception_handler.h" | 27 #include "breakpad/src/client/linux/handler/exception_handler.h" |
| 28 #include "breakpad/src/client/linux/minidump_writer/linux_dumper.h" | 28 #include "breakpad/src/client/linux/minidump_writer/linux_dumper.h" |
| 29 #include "breakpad/src/client/linux/minidump_writer/minidump_writer.h" | 29 #include "breakpad/src/client/linux/minidump_writer/minidump_writer.h" |
| 30 #include "chrome/app/breakpad_linux.h" | 30 #include "chrome/app/breakpad_linux_impl.h" |
| 31 #include "chrome/common/chrome_paths.h" | 31 #include "chrome/common/chrome_paths.h" |
| 32 #include "chrome/common/env_vars.h" | 32 #include "chrome/common/env_vars.h" |
| 33 #include "content/public/browser/browser_thread.h" | 33 #include "content/public/browser/browser_thread.h" |
| 34 | 34 |
| 35 #if defined(OS_ANDROID) | 35 #if defined(OS_ANDROID) |
| 36 #include <sys/linux-syscalls.h> | 36 #include <sys/linux-syscalls.h> |
| 37 | 37 |
| 38 #define SYS_read __NR_read | 38 #define SYS_read __NR_read |
| 39 #endif | 39 #endif |
| 40 | 40 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 53 void CrashDumpTask(CrashHandlerHostLinux* handler, BreakpadInfo* info) { | 53 void CrashDumpTask(CrashHandlerHostLinux* handler, BreakpadInfo* info) { |
| 54 if (handler->IsShuttingDown()) | 54 if (handler->IsShuttingDown()) |
| 55 return; | 55 return; |
| 56 | 56 |
| 57 HandleCrashDump(*info); | 57 HandleCrashDump(*info); |
| 58 delete[] info->filename; | 58 delete[] info->filename; |
| 59 delete[] info->process_type; | 59 delete[] info->process_type; |
| 60 delete[] info->crash_url; | 60 delete[] info->crash_url; |
| 61 delete[] info->guid; | 61 delete[] info->guid; |
| 62 delete[] info->distro; | 62 delete[] info->distro; |
| 63 delete info->crash_keys; | |
| 63 delete info; | 64 delete info; |
| 64 } | 65 } |
| 65 | 66 |
| 66 } // namespace | 67 } // namespace |
| 67 | 68 |
| 68 // Since classes derived from CrashHandlerHostLinux are singletons, it's only | 69 // Since classes derived from CrashHandlerHostLinux are singletons, it's only |
| 69 // destroyed at the end of the processes lifetime, which is greater in span than | 70 // destroyed at the end of the processes lifetime, which is greater in span than |
| 70 // the lifetime of the IO message loop. Thus, all calls to base::Bind() use | 71 // the lifetime of the IO message loop. Thus, all calls to base::Bind() use |
| 71 // non-refcounted pointers. | 72 // non-refcounted pointers. |
| 72 | 73 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 121 void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) { | 122 void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) { |
| 122 DCHECK_EQ(fd, browser_socket_); | 123 DCHECK_EQ(fd, browser_socket_); |
| 123 | 124 |
| 124 // A process has crashed and has signaled us by writing a datagram | 125 // A process has crashed and has signaled us by writing a datagram |
| 125 // to the death signal socket. The datagram contains the crash context needed | 126 // to the death signal socket. The datagram contains the crash context needed |
| 126 // for writing the minidump as well as a file descriptor and a credentials | 127 // for writing the minidump as well as a file descriptor and a credentials |
| 127 // block so that they can't lie about their pid. | 128 // block so that they can't lie about their pid. |
| 128 // | 129 // |
| 129 // The message sender is in chrome/app/breakpad_linux.cc. | 130 // The message sender is in chrome/app/breakpad_linux.cc. |
| 130 | 131 |
| 131 #if !defined(ADDRESS_SANITIZER) | |
| 132 const size_t kIovSize = 8; | |
| 133 #else | |
| 134 const size_t kIovSize = 9; | |
| 135 #endif | |
| 136 | |
| 137 struct msghdr msg = {0}; | 132 struct msghdr msg = {0}; |
| 138 struct iovec iov[kIovSize]; | 133 struct iovec iov[kCrashIovSize]; |
| 139 | 134 |
| 140 // Freed in WriteDumpFile(); | 135 // Freed in WriteDumpFile(); |
| 141 char* crash_context = new char[kCrashContextSize]; | 136 char* crash_context = new char[kCrashContextSize]; |
| 142 // Freed in CrashDumpTask(); | 137 // Freed in CrashDumpTask(); |
| 143 char* guid = new char[kGuidSize + 1]; | 138 char* guid = new char[kGuidSize + 1]; |
| 144 char* crash_url = new char[kMaxActiveURLSize + 1]; | 139 char* crash_url = new char[kMaxActiveURLSize + 1]; |
| 145 char* distro = new char[kDistroSize + 1]; | 140 char* distro = new char[kDistroSize + 1]; |
| 146 #if defined(ADDRESS_SANITIZER) | 141 #if defined(ADDRESS_SANITIZER) |
| 147 asan_report_str_ = new char[kMaxAsanReportSize + 1]; | 142 asan_report_str_ = new char[kMaxAsanReportSize + 1]; |
| 148 #endif | 143 #endif |
| 149 | 144 |
| 145 // Deleted in CrashDumpTask. | |
|
Lei Zhang
2013/05/28 22:02:24
nit: Would you mind writing CrashDumpTask() to be
Robert Sesek
2013/05/29 18:39:45
Done.
| |
| 146 CrashKeyStorage* crash_keys = new CrashKeyStorage; | |
| 147 google_breakpad::SerializedNonAllocatingMap* serialzed_crash_keys; | |
|
Lei Zhang
2013/05/28 22:02:24
nit: typo in var name
Robert Sesek
2013/05/29 18:39:45
Done.
| |
| 148 size_t crash_keys_size = crash_keys->Serialize( | |
| 149 const_cast<const google_breakpad::SerializedNonAllocatingMap**>( | |
| 150 &serialzed_crash_keys)); | |
| 151 | |
| 150 char* tid_buf_addr = NULL; | 152 char* tid_buf_addr = NULL; |
| 151 int tid_fd = -1; | 153 int tid_fd = -1; |
| 152 uint64_t uptime; | 154 uint64_t uptime; |
| 153 size_t oom_size; | 155 size_t oom_size; |
| 154 char control[kControlMsgSize]; | 156 char control[kControlMsgSize]; |
| 155 const ssize_t expected_msg_size = | 157 const ssize_t expected_msg_size = |
| 156 kCrashContextSize + | 158 kCrashContextSize + |
| 157 kGuidSize + 1 + | 159 kGuidSize + 1 + |
| 158 kMaxActiveURLSize + 1 + | 160 kMaxActiveURLSize + 1 + |
| 159 kDistroSize + 1 + | 161 kDistroSize + 1 + |
| 160 sizeof(tid_buf_addr) + sizeof(tid_fd) + | 162 sizeof(tid_buf_addr) + sizeof(tid_fd) + |
| 161 sizeof(uptime) + | 163 sizeof(uptime) + |
| 162 #if defined(ADDRESS_SANITIZER) | 164 #if defined(ADDRESS_SANITIZER) |
| 163 kMaxAsanReportSize + 1 + | 165 kMaxAsanReportSize + 1 + |
| 164 #endif | 166 #endif |
| 165 sizeof(oom_size); | 167 sizeof(oom_size) + |
| 168 crash_keys_size; | |
| 166 iov[0].iov_base = crash_context; | 169 iov[0].iov_base = crash_context; |
| 167 iov[0].iov_len = kCrashContextSize; | 170 iov[0].iov_len = kCrashContextSize; |
| 168 iov[1].iov_base = guid; | 171 iov[1].iov_base = guid; |
| 169 iov[1].iov_len = kGuidSize + 1; | 172 iov[1].iov_len = kGuidSize + 1; |
| 170 iov[2].iov_base = crash_url; | 173 iov[2].iov_base = crash_url; |
| 171 iov[2].iov_len = kMaxActiveURLSize + 1; | 174 iov[2].iov_len = kMaxActiveURLSize + 1; |
| 172 iov[3].iov_base = distro; | 175 iov[3].iov_base = distro; |
| 173 iov[3].iov_len = kDistroSize + 1; | 176 iov[3].iov_len = kDistroSize + 1; |
| 174 iov[4].iov_base = &tid_buf_addr; | 177 iov[4].iov_base = &tid_buf_addr; |
| 175 iov[4].iov_len = sizeof(tid_buf_addr); | 178 iov[4].iov_len = sizeof(tid_buf_addr); |
| 176 iov[5].iov_base = &tid_fd; | 179 iov[5].iov_base = &tid_fd; |
| 177 iov[5].iov_len = sizeof(tid_fd); | 180 iov[5].iov_len = sizeof(tid_fd); |
| 178 iov[6].iov_base = &uptime; | 181 iov[6].iov_base = &uptime; |
| 179 iov[6].iov_len = sizeof(uptime); | 182 iov[6].iov_len = sizeof(uptime); |
| 180 iov[7].iov_base = &oom_size; | 183 iov[7].iov_base = &oom_size; |
| 181 iov[7].iov_len = sizeof(oom_size); | 184 iov[7].iov_len = sizeof(oom_size); |
| 185 iov[8].iov_base = serialzed_crash_keys; | |
| 186 iov[8].iov_len = crash_keys_size; | |
| 182 #if defined(ADDRESS_SANITIZER) | 187 #if defined(ADDRESS_SANITIZER) |
| 183 iov[8].iov_base = asan_report_str_; | 188 iov[9].iov_base = asan_report_str_; |
| 184 iov[8].iov_len = kMaxAsanReportSize + 1; | 189 iov[9].iov_len = kMaxAsanReportSize + 1; |
| 185 #endif | 190 #endif |
| 186 msg.msg_iov = iov; | 191 msg.msg_iov = iov; |
| 187 msg.msg_iovlen = kIovSize; | 192 msg.msg_iovlen = kCrashIovSize; |
| 188 msg.msg_control = control; | 193 msg.msg_control = control; |
| 189 msg.msg_controllen = kControlMsgSize; | 194 msg.msg_controllen = kControlMsgSize; |
| 190 | 195 |
| 191 const ssize_t msg_size = HANDLE_EINTR(recvmsg(browser_socket_, &msg, 0)); | 196 const ssize_t msg_size = HANDLE_EINTR(recvmsg(browser_socket_, &msg, 0)); |
| 192 if (msg_size != expected_msg_size) { | 197 if (msg_size != expected_msg_size) { |
| 193 LOG(ERROR) << "Error reading from death signal socket. Crash dumping" | 198 LOG(ERROR) << "Error reading from death signal socket. Crash dumping" |
| 194 << " is disabled." | 199 << " is disabled." |
| 195 << " msg_size:" << msg_size | 200 << " msg_size:" << msg_size |
| 196 << " errno:" << errno; | 201 << " errno:" << errno; |
| 197 file_descriptor_watcher_.StopWatchingFileDescriptor(); | 202 file_descriptor_watcher_.StopWatchingFileDescriptor(); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 339 | 344 |
| 340 info->distro_length = strlen(distro); | 345 info->distro_length = strlen(distro); |
| 341 info->distro = distro; | 346 info->distro = distro; |
| 342 #if defined(OS_ANDROID) | 347 #if defined(OS_ANDROID) |
| 343 // Nothing gets uploaded in android. | 348 // Nothing gets uploaded in android. |
| 344 info->upload = false; | 349 info->upload = false; |
| 345 #else | 350 #else |
| 346 info->upload = (getenv(env_vars::kHeadless) == NULL); | 351 info->upload = (getenv(env_vars::kHeadless) == NULL); |
| 347 #endif | 352 #endif |
| 348 | 353 |
| 354 info->crash_keys = crash_keys; | |
| 355 | |
| 349 #if defined(ADDRESS_SANITIZER) | 356 #if defined(ADDRESS_SANITIZER) |
| 350 info->asan_report_str = asan_report_str_; | 357 info->asan_report_str = asan_report_str_; |
| 351 info->asan_report_length = strlen(asan_report_str_); | 358 info->asan_report_length = strlen(asan_report_str_); |
| 352 #endif | 359 #endif |
| 353 info->process_start_time = uptime; | 360 info->process_start_time = uptime; |
| 354 info->oom_size = oom_size; | 361 info->oom_size = oom_size; |
| 355 | 362 |
| 356 BrowserThread::PostTask( | 363 BrowserThread::PostTask( |
| 357 BrowserThread::FILE, FROM_HERE, | 364 BrowserThread::FILE, FROM_HERE, |
| 358 base::Bind(&CrashHandlerHostLinux::WriteDumpFile, | 365 base::Bind(&CrashHandlerHostLinux::WriteDumpFile, |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 530 } | 537 } |
| 531 | 538 |
| 532 void RendererCrashHandlerHostLinux::SetProcessType() { | 539 void RendererCrashHandlerHostLinux::SetProcessType() { |
| 533 process_type_ = "renderer"; | 540 process_type_ = "renderer"; |
| 534 } | 541 } |
| 535 | 542 |
| 536 // static | 543 // static |
| 537 RendererCrashHandlerHostLinux* RendererCrashHandlerHostLinux::GetInstance() { | 544 RendererCrashHandlerHostLinux* RendererCrashHandlerHostLinux::GetInstance() { |
| 538 return Singleton<RendererCrashHandlerHostLinux>::get(); | 545 return Singleton<RendererCrashHandlerHostLinux>::get(); |
| 539 } | 546 } |
| OLD | NEW |