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

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

Issue 10860006: Breakpad support for ASan: take 2. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/crash_handler_host_linux.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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>
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) { 121 void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) {
122 DCHECK_EQ(fd, browser_socket_); 122 DCHECK_EQ(fd, browser_socket_);
123 123
124 // A process has crashed and has signaled us by writing a datagram 124 // 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 125 // 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 126 // for writing the minidump as well as a file descriptor and a credentials
127 // block so that they can't lie about their pid. 127 // block so that they can't lie about their pid.
128 // 128 //
129 // The message sender is in chrome/app/breakpad_linux.cc. 129 // The message sender is in chrome/app/breakpad_linux.cc.
130 130
131 #if !defined(ADDRESS_SANITIZER)
131 const size_t kIovSize = 8; 132 const size_t kIovSize = 8;
133 #else
134 const size_t kIovSize = 9;
135 #endif
136
132 struct msghdr msg = {0}; 137 struct msghdr msg = {0};
133 struct iovec iov[kIovSize]; 138 struct iovec iov[kIovSize];
134 139
135 // Freed in WriteDumpFile(); 140 // Freed in WriteDumpFile();
136 char* crash_context = new char[kCrashContextSize]; 141 char* crash_context = new char[kCrashContextSize];
137 // Freed in CrashDumpTask(); 142 // Freed in CrashDumpTask();
138 char* guid = new char[kGuidSize + 1]; 143 char* guid = new char[kGuidSize + 1];
139 char* crash_url = new char[kMaxActiveURLSize + 1]; 144 char* crash_url = new char[kMaxActiveURLSize + 1];
140 char* distro = new char[kDistroSize + 1]; 145 char* distro = new char[kDistroSize + 1];
146 #if defined(ADDRESS_SANITIZER)
147 asan_report_str_ = new char[kMaxAsanReportSize + 1];
148 #endif
141 149
142 char* tid_buf_addr = NULL; 150 char* tid_buf_addr = NULL;
143 int tid_fd = -1; 151 int tid_fd = -1;
144 uint64_t uptime; 152 uint64_t uptime;
145 size_t oom_size; 153 size_t oom_size;
146 char control[kControlMsgSize]; 154 char control[kControlMsgSize];
147 const ssize_t expected_msg_size = 155 const ssize_t expected_msg_size =
148 kCrashContextSize + 156 kCrashContextSize +
149 kGuidSize + 1 + 157 kGuidSize + 1 +
150 kMaxActiveURLSize + 1 + 158 kMaxActiveURLSize + 1 +
151 kDistroSize + 1 + 159 kDistroSize + 1 +
152 sizeof(tid_buf_addr) + sizeof(tid_fd) + 160 sizeof(tid_buf_addr) + sizeof(tid_fd) +
153 sizeof(uptime) + 161 sizeof(uptime) +
162 #if defined(ADDRESS_SANITIZER)
163 kMaxAsanReportSize + 1 +
164 #endif
154 sizeof(oom_size); 165 sizeof(oom_size);
155
156 iov[0].iov_base = crash_context; 166 iov[0].iov_base = crash_context;
157 iov[0].iov_len = kCrashContextSize; 167 iov[0].iov_len = kCrashContextSize;
158 iov[1].iov_base = guid; 168 iov[1].iov_base = guid;
159 iov[1].iov_len = kGuidSize + 1; 169 iov[1].iov_len = kGuidSize + 1;
160 iov[2].iov_base = crash_url; 170 iov[2].iov_base = crash_url;
161 iov[2].iov_len = kMaxActiveURLSize + 1; 171 iov[2].iov_len = kMaxActiveURLSize + 1;
162 iov[3].iov_base = distro; 172 iov[3].iov_base = distro;
163 iov[3].iov_len = kDistroSize + 1; 173 iov[3].iov_len = kDistroSize + 1;
164 iov[4].iov_base = &tid_buf_addr; 174 iov[4].iov_base = &tid_buf_addr;
165 iov[4].iov_len = sizeof(tid_buf_addr); 175 iov[4].iov_len = sizeof(tid_buf_addr);
166 iov[5].iov_base = &tid_fd; 176 iov[5].iov_base = &tid_fd;
167 iov[5].iov_len = sizeof(tid_fd); 177 iov[5].iov_len = sizeof(tid_fd);
168 iov[6].iov_base = &uptime; 178 iov[6].iov_base = &uptime;
169 iov[6].iov_len = sizeof(uptime); 179 iov[6].iov_len = sizeof(uptime);
170 iov[7].iov_base = &oom_size; 180 iov[7].iov_base = &oom_size;
171 iov[7].iov_len = sizeof(oom_size); 181 iov[7].iov_len = sizeof(oom_size);
182 #if defined(ADDRESS_SANITIZER)
183 iov[8].iov_base = asan_report_str_;
184 iov[8].iov_len = kMaxAsanReportSize + 1;
185 #endif
172 msg.msg_iov = iov; 186 msg.msg_iov = iov;
173 msg.msg_iovlen = kIovSize; 187 msg.msg_iovlen = kIovSize;
174 msg.msg_control = control; 188 msg.msg_control = control;
175 msg.msg_controllen = kControlMsgSize; 189 msg.msg_controllen = kControlMsgSize;
176 190
177 const ssize_t msg_size = HANDLE_EINTR(recvmsg(browser_socket_, &msg, 0)); 191 const ssize_t msg_size = HANDLE_EINTR(recvmsg(browser_socket_, &msg, 0));
178 if (msg_size != expected_msg_size) { 192 if (msg_size != expected_msg_size) {
179 LOG(ERROR) << "Error reading from death signal socket. Crash dumping" 193 LOG(ERROR) << "Error reading from death signal socket. Crash dumping"
180 << " is disabled." 194 << " is disabled."
181 << " msg_size:" << msg_size 195 << " msg_size:" << msg_size
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 info->guid = guid; 337 info->guid = guid;
324 338
325 info->distro_length = strlen(distro); 339 info->distro_length = strlen(distro);
326 info->distro = distro; 340 info->distro = distro;
327 #if defined(OS_ANDROID) 341 #if defined(OS_ANDROID)
328 // Nothing gets uploaded in android. 342 // Nothing gets uploaded in android.
329 info->upload = false; 343 info->upload = false;
330 #else 344 #else
331 info->upload = (getenv(env_vars::kHeadless) == NULL); 345 info->upload = (getenv(env_vars::kHeadless) == NULL);
332 #endif 346 #endif
347
348 #if defined(ADDRESS_SANITIZER)
349 info->asan_report_str = asan_report_str_;
350 info->asan_report_length = strlen(asan_report_str_);
351 #endif
333 info->process_start_time = uptime; 352 info->process_start_time = uptime;
334 info->oom_size = oom_size; 353 info->oom_size = oom_size;
335 354
336 BrowserThread::PostTask( 355 BrowserThread::PostTask(
337 BrowserThread::FILE, FROM_HERE, 356 BrowserThread::FILE, FROM_HERE,
338 base::Bind(&CrashHandlerHostLinux::WriteDumpFile, 357 base::Bind(&CrashHandlerHostLinux::WriteDumpFile,
339 base::Unretained(this), 358 base::Unretained(this),
340 info, 359 info,
341 crashing_pid, 360 crashing_pid,
342 crash_context, 361 crash_context,
343 signal_fd)); 362 signal_fd));
344 } 363 }
345 364
346 void CrashHandlerHostLinux::WriteDumpFile(BreakpadInfo* info, 365 void CrashHandlerHostLinux::WriteDumpFile(BreakpadInfo* info,
347 pid_t crashing_pid, 366 pid_t crashing_pid,
348 char* crash_context, 367 char* crash_context,
349 int signal_fd) { 368 int signal_fd) {
350 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 369 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
351 370
352 FilePath dumps_path("/tmp"); 371 FilePath dumps_path("/tmp");
353 PathService::Get(base::DIR_TEMP, &dumps_path); 372 PathService::Get(base::DIR_TEMP, &dumps_path);
354 if (!info->upload) 373 if (!info->upload)
355 PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path); 374 PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path);
356 const uint64 rand = base::RandUint64(); 375 const uint64 rand = base::RandUint64();
357 const std::string minidump_filename = 376 const std::string minidump_filename =
358 base::StringPrintf("%s/chromium-%s-minidump-%016" PRIx64 ".dmp", 377 base::StringPrintf("%s/chromium-%s-minidump-%016" PRIx64 ".dmp",
359 dumps_path.value().c_str(), 378 dumps_path.value().c_str(),
360 process_type_.c_str(), 379 process_type_.c_str(),
361 rand); 380 rand);
381
362 if (!google_breakpad::WriteMinidump(minidump_filename.c_str(), 382 if (!google_breakpad::WriteMinidump(minidump_filename.c_str(),
363 crashing_pid, crash_context, 383 crashing_pid, crash_context,
364 kCrashContextSize)) { 384 kCrashContextSize)) {
365 LOG(ERROR) << "Failed to write crash dump for pid " << crashing_pid; 385 LOG(ERROR) << "Failed to write crash dump for pid " << crashing_pid;
366 } 386 }
387 #if defined(ADDRESS_SANITIZER)
388 // Create a temporary file holding the AddressSanitizer report.
389 const std::string log_filename =
390 base::StringPrintf("%s/chromium-%s-minidump-%016" PRIx64 ".log",
391 dumps_path.value().c_str(),
392 process_type_.c_str(),
393 rand);
394 FILE* logfile = fopen(log_filename.c_str(), "w");
395 CHECK(logfile);
396 fprintf(logfile, "%s", asan_report_str_);
397 fclose(logfile);
398 #endif
399
367 delete[] crash_context; 400 delete[] crash_context;
368 401
369 // Freed in CrashDumpTask(); 402 // Freed in CrashDumpTask();
370 char* minidump_filename_str = new char[minidump_filename.length() + 1]; 403 char* minidump_filename_str = new char[minidump_filename.length() + 1];
371 minidump_filename.copy(minidump_filename_str, minidump_filename.length()); 404 minidump_filename.copy(minidump_filename_str, minidump_filename.length());
372 minidump_filename_str[minidump_filename.length()] = '\0'; 405 minidump_filename_str[minidump_filename.length()] = '\0';
373 info->filename = minidump_filename_str; 406 info->filename = minidump_filename_str;
407 #if defined(ADDRESS_SANITIZER)
408 char* minidump_log_filename_str = new char[minidump_filename.length() + 1];
409 minidump_filename.copy(minidump_log_filename_str, minidump_filename.length());
410 memcpy(minidump_log_filename_str + minidump_filename.length() - 3, "log", 3);
411 minidump_log_filename_str[minidump_filename.length()] = '\0';
412 info->log_filename = minidump_log_filename_str;
413 #endif
374 info->pid = crashing_pid; 414 info->pid = crashing_pid;
375 415
376 BrowserThread::PostTask( 416 BrowserThread::PostTask(
377 BrowserThread::IO, FROM_HERE, 417 BrowserThread::IO, FROM_HERE,
378 base::Bind(&CrashHandlerHostLinux::QueueCrashDumpTask, 418 base::Bind(&CrashHandlerHostLinux::QueueCrashDumpTask,
379 base::Unretained(this), 419 base::Unretained(this),
380 info, 420 info,
381 signal_fd)); 421 signal_fd));
382 } 422 }
383 423
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 } 526 }
487 527
488 void RendererCrashHandlerHostLinux::SetProcessType() { 528 void RendererCrashHandlerHostLinux::SetProcessType() {
489 process_type_ = "renderer"; 529 process_type_ = "renderer";
490 } 530 }
491 531
492 // static 532 // static
493 RendererCrashHandlerHostLinux* RendererCrashHandlerHostLinux::GetInstance() { 533 RendererCrashHandlerHostLinux* RendererCrashHandlerHostLinux::GetInstance() {
494 return Singleton<RendererCrashHandlerHostLinux>::get(); 534 return Singleton<RendererCrashHandlerHostLinux>::get();
495 } 535 }
OLDNEW
« no previous file with comments | « chrome/browser/crash_handler_host_linux.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698