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 |