Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: chrome/browser/crash_handler_host_linux.cc

Issue 16019015: [Linux] Implement the crash key logging mechanism. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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 }
OLDNEW
« chrome/app/breakpad_linux.cc ('K') | « chrome/app/breakpad_linux_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698