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

Unified Diff: chrome/app/breakpad_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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/app/breakpad_linux.h ('k') | chrome/browser/crash_handler_host_linux.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/app/breakpad_linux.cc
===================================================================
--- chrome/app/breakpad_linux.cc (revision 152746)
+++ chrome/app/breakpad_linux.cc (working copy)
@@ -10,6 +10,7 @@
#include <fcntl.h>
#include <poll.h>
+#include <signal.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/time.h>
@@ -54,6 +55,10 @@
#include "sandbox/linux/seccomp-legacy/linux_syscall_support.h"
#endif
+#if defined(ADDRESS_SANITIZER)
+#include <ucontext.h> // for getcontext().
+#endif
+
#if defined(OS_ANDROID)
#define STAT_STRUCT struct stat
#define FSTAT_FUNC fstat
@@ -73,12 +78,21 @@
namespace {
+#if !defined(ADDRESS_SANITIZER)
const char kUploadURL[] = "https://clients2.google.com/cr/report";
+#else
+// AddressSanitizer should currently upload the crash reports to the staging
+// crash server.
+const char kUploadURL[] = "https://clients2.google.com/cr/staging_report";
+#endif
bool g_is_crash_reporter_enabled = false;
uint64_t g_process_start_time = 0;
char* g_crash_log_path = NULL;
ExceptionHandler* g_breakpad = NULL;
+#if defined(ADDRESS_SANITIZER)
+const char* g_asan_report_str = NULL;
+#endif
// Writes the value |v| as 16 hex characters to the memory pointed at by
// |output|.
@@ -171,6 +185,9 @@
const char g_quote_msg[] = "\"";
const char g_dashdash_msg[] = "--";
const char g_dump_msg[] = "upload_file_minidump\"; filename=\"dump\"";
+#if defined(ADDRESS_SANITIZER)
+const char g_log_msg[] = "upload_file_log\"; filename=\"log\"";
+#endif
const char g_content_type_msg[] = "Content-Type: application/octet-stream";
// MimeWriter manages an iovec for writing MIMEs to a file.
@@ -210,10 +227,10 @@
size_t chunk_size,
bool strip_trailing_spaces);
- // Add binary file dump. Currently this is only done once, so the name is
- // fixed.
- void AddFileDump(uint8_t* file_data,
- size_t file_size);
+ // Add binary file contents to be uploaded with the specified filename.
+ void AddFileContents(const char* filename_msg,
+ uint8_t* file_data,
+ size_t file_size);
// Flush any pending iovecs to the output file.
void Flush() {
@@ -312,10 +329,10 @@
}
}
-void MimeWriter::AddFileDump(uint8_t* file_data,
- size_t file_size) {
+void MimeWriter::AddFileContents(const char* filename_msg, uint8_t* file_data,
+ size_t file_size) {
AddString(g_form_data_msg);
- AddString(g_dump_msg);
+ AddString(filename_msg);
AddString(g_rn);
AddString(g_content_type_msg);
AddString(g_rn);
@@ -372,6 +389,15 @@
BreakpadInfo info;
info.filename = minidump.path();
+#if defined(ADDRESS_SANITIZER)
+ google_breakpad::PageAllocator allocator;
+ const size_t log_path_len = my_strlen(minidump.path());
+ char* log_path = reinterpret_cast<char*>(allocator.Alloc(log_path_len + 1));
+ my_memcpy(log_path, minidump.path(), log_path_len);
+ my_memcpy(log_path + log_path_len - 4, ".log", 4);
+ log_path[log_path_len] = '\0';
+ info.log_filename = log_path;
+#endif
info.process_type = "browser";
info.process_type_length = 7;
info.crash_url = NULL;
@@ -404,6 +430,18 @@
}
#endif
+#if defined(ADDRESS_SANITIZER)
+extern "C"
+void __asan_set_error_report_callback(void (*cb)(const char*));
+
+extern "C"
+void AsanLinuxBreakpadCallback(const char* report) {
+ g_asan_report_str = report;
+ // Send minidump here.
+ g_breakpad->SimulateSignalDelivery(SIGKILL);
+}
+#endif
+
void EnableCrashDumping(bool unattended) {
g_is_crash_reporter_enabled = true;
@@ -483,7 +521,12 @@
static const unsigned kControlMsgSpaceSize = CMSG_SPACE(kControlMsgSize);
static const unsigned kControlMsgLenSize = CMSG_LEN(kControlMsgSize);
+#if !defined(ADDRESS_SANITIZER)
const size_t kIovSize = 8;
+#else
+ // Additional field to pass the AddressSanitizer log to the crash handler.
+ const size_t kIovSize = 9;
+#endif
struct kernel_msghdr msg;
my_memset(&msg, 0, sizeof(struct kernel_msghdr));
struct kernel_iovec iov[kIovSize];
@@ -503,6 +546,10 @@
iov[6].iov_len = sizeof(g_process_start_time);
iov[7].iov_base = &base::g_oom_size;
iov[7].iov_len = sizeof(base::g_oom_size);
+#if defined(ADDRESS_SANITIZER)
+ iov[8].iov_base = const_cast<char*>(g_asan_report_str);
+ iov[8].iov_len = kMaxAsanReportSize + 1;
+#endif
msg.msg_iov = iov;
msg.msg_iovlen = kIovSize;
@@ -551,40 +598,59 @@
} // namespace
-void HandleCrashDump(const BreakpadInfo& info) {
+void LoadDataFromFile(google_breakpad::PageAllocator& allocator,
+ const BreakpadInfo& info, const char* filename,
+ int* fd, uint8_t** file_data, size_t* size) {
// WARNING: this code runs in a compromised context. It may not call into
// libc nor allocate memory normally.
+ *fd = sys_open(filename, O_RDONLY, 0);
+ *size = 0;
- const int dumpfd = sys_open(info.filename, O_RDONLY, 0);
- if (dumpfd < 0) {
+ if (*fd < 0) {
static const char msg[] = "Cannot upload crash dump: failed to open\n";
WriteLog(msg, sizeof(msg));
return;
}
STAT_STRUCT st;
- if (FSTAT_FUNC(dumpfd, &st) != 0) {
+ if (FSTAT_FUNC(*fd, &st) != 0) {
static const char msg[] = "Cannot upload crash dump: stat failed\n";
WriteLog(msg, sizeof(msg));
- IGNORE_RET(sys_close(dumpfd));
+ IGNORE_RET(sys_close(*fd));
return;
}
- google_breakpad::PageAllocator allocator;
-
- uint8_t* dump_data = reinterpret_cast<uint8_t*>(allocator.Alloc(st.st_size));
- if (!dump_data) {
+ *file_data = reinterpret_cast<uint8_t*>(allocator.Alloc(st.st_size));
+ if (!(*file_data)) {
static const char msg[] = "Cannot upload crash dump: cannot alloc\n";
WriteLog(msg, sizeof(msg));
- IGNORE_RET(sys_close(dumpfd));
+ IGNORE_RET(sys_close(*fd));
return;
}
+ my_memset(*file_data, 0xf, st.st_size);
- sys_read(dumpfd, dump_data, st.st_size);
- IGNORE_RET(sys_close(dumpfd));
+ *size = st.st_size;
+ sys_read(*fd, *file_data, *size);
+ IGNORE_RET(sys_close(*fd));
+}
+void HandleCrashDump(const BreakpadInfo& info) {
+ int dumpfd;
+ size_t dump_size;
+ uint8_t *dump_data;
+ google_breakpad::PageAllocator allocator;
+ LoadDataFromFile(allocator, info, info.filename,
+ &dumpfd, &dump_data, &dump_size);
+#if defined(ADDRESS_SANITIZER)
+ int logfd;
+ size_t log_size;
+ uint8_t *log_data;
+ // Load the AddressSanitizer log into log_data.
+ LoadDataFromFile(allocator, info, info.log_filename,
+ &logfd, &log_data, &log_size);
+#endif
+
// We need to build a MIME block for uploading to the server. Since we are
// going to fork and run wget, it needs to be written to a temp file.
-
const int ufd = sys_open("/dev/urandom", O_RDONLY, 0);
if (ufd < 0) {
static const char msg[] = "Cannot upload crash dump because /dev/urandom"
@@ -916,7 +982,12 @@
writer.Flush();
}
- writer.AddFileDump(dump_data, st.st_size);
+ writer.AddFileContents(g_dump_msg, dump_data, dump_size);
+#if defined(ADDRESS_SANITIZER)
+ // Append a multipart boundary and the contents of the AddressSanitizer log.
+ writer.AddBoundary();
+ writer.AddFileContents(g_log_msg, log_data, log_size);
+#endif
writer.AddEnd();
writer.Flush();
@@ -1097,6 +1168,9 @@
// Helper process.
IGNORE_RET(sys_unlink(info.filename));
+#if defined(ADDRESS_SANITIZER)
+ IGNORE_RET(sys_unlink(info.log_filename));
+#endif
IGNORE_RET(sys_unlink(temp_file));
sys__exit(0);
}
@@ -1158,6 +1232,10 @@
g_process_start_time = 0;
logging::SetDumpWithoutCrashingFunction(&DumpProcess);
+#if defined(ADDRESS_SANITIZER)
+ // Register the callback for AddressSanitizer error reporting.
+ __asan_set_error_report_callback(AsanLinuxBreakpadCallback);
+#endif
}
bool IsCrashReporterEnabled() {
« no previous file with comments | « chrome/app/breakpad_linux.h ('k') | chrome/browser/crash_handler_host_linux.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698