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 // For linux_syscall_support.h. This makes it safe to call embedded system | 5 // For linux_syscall_support.h. This makes it safe to call embedded system |
| 6 // calls when in seccomp mode. | 6 // calls when in seccomp mode. |
| 7 #define SYS_SYSCALL_ENTRYPOINT "playground$syscallEntryPoint" | 7 #define SYS_SYSCALL_ENTRYPOINT "playground$syscallEntryPoint" |
| 8 | 8 |
| 9 #include "chrome/app/breakpad_linux.h" | 9 #include "chrome/app/breakpad_linux.h" |
| 10 | 10 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 47 #include <android/log.h> | 47 #include <android/log.h> |
| 48 #include <sys/stat.h> | 48 #include <sys/stat.h> |
| 49 | 49 |
| 50 #include "base/android/build_info.h" | 50 #include "base/android/build_info.h" |
| 51 #include "base/android/path_utils.h" | 51 #include "base/android/path_utils.h" |
| 52 #include "third_party/lss/linux_syscall_support.h" | 52 #include "third_party/lss/linux_syscall_support.h" |
| 53 #else | 53 #else |
| 54 #include "sandbox/linux/seccomp-legacy/linux_syscall_support.h" | 54 #include "sandbox/linux/seccomp-legacy/linux_syscall_support.h" |
| 55 #endif | 55 #endif |
| 56 | 56 |
| 57 #if defined(ADDRESS_SANITIZER) | |
| 58 #include <ucontext.h> // for getcontext(). | |
| 59 #endif | |
| 60 | |
| 57 #if defined(OS_ANDROID) | 61 #if defined(OS_ANDROID) |
| 58 #define STAT_STRUCT struct stat | 62 #define STAT_STRUCT struct stat |
| 59 #define FSTAT_FUNC fstat | 63 #define FSTAT_FUNC fstat |
| 60 #else | 64 #else |
| 61 #define STAT_STRUCT struct kernel_stat | 65 #define STAT_STRUCT struct kernel_stat |
| 62 #define FSTAT_FUNC sys_fstat | 66 #define FSTAT_FUNC sys_fstat |
| 63 #endif | 67 #endif |
| 64 | 68 |
| 65 // Some versions of gcc are prone to warn about unused return values. In cases | 69 // Some versions of gcc are prone to warn about unused return values. In cases |
| 66 // where we either a) know the call cannot fail, or b) there is nothing we | 70 // where we either a) know the call cannot fail, or b) there is nothing we |
| 67 // can do when a call fails, we mark the return code as ignored. This avoids | 71 // can do when a call fails, we mark the return code as ignored. This avoids |
| 68 // spurious compiler warnings. | 72 // spurious compiler warnings. |
| 69 #define IGNORE_RET(x) do { if (x); } while (0) | 73 #define IGNORE_RET(x) do { if (x); } while (0) |
| 70 | 74 |
| 71 using google_breakpad::ExceptionHandler; | 75 using google_breakpad::ExceptionHandler; |
| 72 using google_breakpad::MinidumpDescriptor; | 76 using google_breakpad::MinidumpDescriptor; |
| 73 | 77 |
| 74 namespace { | 78 namespace { |
| 75 | 79 |
| 80 #if !defined(ADDRESS_SANITIZER) | |
| 76 const char kUploadURL[] = "https://clients2.google.com/cr/report"; | 81 const char kUploadURL[] = "https://clients2.google.com/cr/report"; |
| 82 #else | |
| 83 // AddressSanitizer should currently upload the crash reports to the staging | |
| 84 // crash server. | |
| 85 const char kUploadURL[] = "https://clients2.google.com/cr/staging_report"; | |
| 86 #endif | |
| 77 | 87 |
| 78 bool g_is_crash_reporter_enabled = false; | 88 bool g_is_crash_reporter_enabled = false; |
| 79 uint64_t g_process_start_time = 0; | 89 uint64_t g_process_start_time = 0; |
| 80 char* g_crash_log_path = NULL; | 90 char* g_crash_log_path = NULL; |
| 81 ExceptionHandler* g_breakpad = NULL; | 91 ExceptionHandler* g_breakpad = NULL; |
| 92 #if defined(ADDRESS_SANITIZER) | |
| 93 char* g_asan_report_str = NULL; | |
| 94 #endif | |
| 82 | 95 |
| 83 // Writes the value |v| as 16 hex characters to the memory pointed at by | 96 // Writes the value |v| as 16 hex characters to the memory pointed at by |
| 84 // |output|. | 97 // |output|. |
| 85 void write_uint64_hex(char* output, uint64_t v) { | 98 void write_uint64_hex(char* output, uint64_t v) { |
| 86 static const char hextable[] = "0123456789abcdef"; | 99 static const char hextable[] = "0123456789abcdef"; |
| 87 | 100 |
| 88 for (int i = 15; i >= 0; --i) { | 101 for (int i = 15; i >= 0; --i) { |
| 89 output[i] = hextable[v & 15]; | 102 output[i] = hextable[v & 15]; |
| 90 v >>= 4; | 103 v >>= 4; |
| 91 } | 104 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 164 return ret; | 177 return ret; |
| 165 } | 178 } |
| 166 #endif | 179 #endif |
| 167 | 180 |
| 168 // MIME substrings. | 181 // MIME substrings. |
| 169 const char g_rn[] = "\r\n"; | 182 const char g_rn[] = "\r\n"; |
| 170 const char g_form_data_msg[] = "Content-Disposition: form-data; name=\""; | 183 const char g_form_data_msg[] = "Content-Disposition: form-data; name=\""; |
| 171 const char g_quote_msg[] = "\""; | 184 const char g_quote_msg[] = "\""; |
| 172 const char g_dashdash_msg[] = "--"; | 185 const char g_dashdash_msg[] = "--"; |
| 173 const char g_dump_msg[] = "upload_file_minidump\"; filename=\"dump\""; | 186 const char g_dump_msg[] = "upload_file_minidump\"; filename=\"dump\""; |
| 187 #if defined(ADDRESS_SANITIZER) | |
| 188 const char g_log_msg[] = "upload_file_log\"; filename=\"log\""; | |
| 189 #endif | |
| 174 const char g_content_type_msg[] = "Content-Type: application/octet-stream"; | 190 const char g_content_type_msg[] = "Content-Type: application/octet-stream"; |
| 175 | 191 |
| 176 // MimeWriter manages an iovec for writing MIMEs to a file. | 192 // MimeWriter manages an iovec for writing MIMEs to a file. |
| 177 class MimeWriter { | 193 class MimeWriter { |
| 178 public: | 194 public: |
| 179 static const int kIovCapacity = 30; | 195 static const int kIovCapacity = 30; |
| 180 static const size_t kMaxCrashChunkSize = 64; | 196 static const size_t kMaxCrashChunkSize = 64; |
| 181 | 197 |
| 182 MimeWriter(int fd, const char* const mime_boundary); | 198 MimeWriter(int fd, const char* const mime_boundary); |
| 183 ~MimeWriter(); | 199 ~MimeWriter(); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 203 // Append key/value pair, splitting value into chunks no larger than | 219 // Append key/value pair, splitting value into chunks no larger than |
| 204 // |chunk_size|. |chunk_size| cannot be greater than |kMaxCrashChunkSize|. | 220 // |chunk_size|. |chunk_size| cannot be greater than |kMaxCrashChunkSize|. |
| 205 // The msg_type string will have a counter suffix to distinguish each chunk. | 221 // The msg_type string will have a counter suffix to distinguish each chunk. |
| 206 void AddPairDataInChunks(const char* msg_type, | 222 void AddPairDataInChunks(const char* msg_type, |
| 207 size_t msg_type_size, | 223 size_t msg_type_size, |
| 208 const char* msg_data, | 224 const char* msg_data, |
| 209 size_t msg_data_size, | 225 size_t msg_data_size, |
| 210 size_t chunk_size, | 226 size_t chunk_size, |
| 211 bool strip_trailing_spaces); | 227 bool strip_trailing_spaces); |
| 212 | 228 |
| 213 // Add binary file dump. Currently this is only done once, so the name is | 229 // Add binary file contents to be uploaded with the specified filename. |
| 214 // fixed. | 230 void AddFileContents(const char* filename_msg, |
| 215 void AddFileDump(uint8_t* file_data, | 231 uint8_t* file_data, |
| 216 size_t file_size); | 232 size_t file_size); |
| 217 | 233 |
| 218 // Flush any pending iovecs to the output file. | 234 // Flush any pending iovecs to the output file. |
| 219 void Flush() { | 235 void Flush() { |
| 220 IGNORE_RET(sys_writev(fd_, iov_, iov_index_)); | 236 IGNORE_RET(sys_writev(fd_, iov_, iov_index_)); |
| 221 iov_index_ = 0; | 237 iov_index_ = 0; |
| 222 } | 238 } |
| 223 | 239 |
| 224 private: | 240 private: |
| 225 void AddItem(const void* base, size_t size); | 241 void AddItem(const void* base, size_t size); |
| 226 // Minor performance trade-off for easier-to-maintain code. | 242 // Minor performance trade-off for easier-to-maintain code. |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 305 } | 321 } |
| 306 AddString(g_rn); | 322 AddString(g_rn); |
| 307 AddBoundary(); | 323 AddBoundary(); |
| 308 Flush(); | 324 Flush(); |
| 309 | 325 |
| 310 done += chunk_len; | 326 done += chunk_len; |
| 311 msg_length -= chunk_len; | 327 msg_length -= chunk_len; |
| 312 } | 328 } |
| 313 } | 329 } |
| 314 | 330 |
| 315 void MimeWriter::AddFileDump(uint8_t* file_data, | 331 void MimeWriter::AddFileContents(const char* filename_msg, uint8_t* file_data, |
| 316 size_t file_size) { | 332 size_t file_size) { |
| 317 AddString(g_form_data_msg); | 333 AddString(g_form_data_msg); |
| 318 AddString(g_dump_msg); | 334 AddString(filename_msg); |
| 319 AddString(g_rn); | 335 AddString(g_rn); |
| 320 AddString(g_content_type_msg); | 336 AddString(g_content_type_msg); |
| 321 AddString(g_rn); | 337 AddString(g_rn); |
| 322 AddString(g_rn); | 338 AddString(g_rn); |
| 323 AddItem(file_data, file_size); | 339 AddItem(file_data, file_size); |
| 324 AddString(g_rn); | 340 AddString(g_rn); |
| 325 } | 341 } |
| 326 | 342 |
| 327 void MimeWriter::AddItem(const void* base, size_t size) { | 343 void MimeWriter::AddItem(const void* base, size_t size) { |
| 328 // Check if the iovec is full and needs to be flushed to output file. | 344 // Check if the iovec is full and needs to be flushed to output file. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 365 const bool succeeded) { | 381 const bool succeeded) { |
| 366 // WARNING: this code runs in a compromised context. It may not call into | 382 // WARNING: this code runs in a compromised context. It may not call into |
| 367 // libc nor allocate memory normally. | 383 // libc nor allocate memory normally. |
| 368 if (!succeeded) | 384 if (!succeeded) |
| 369 return false; | 385 return false; |
| 370 | 386 |
| 371 DCHECK(!minidump.IsFD()); | 387 DCHECK(!minidump.IsFD()); |
| 372 | 388 |
| 373 BreakpadInfo info; | 389 BreakpadInfo info; |
| 374 info.filename = minidump.path(); | 390 info.filename = minidump.path(); |
| 391 #if defined(ADDRESS_SANITIZER) | |
| 392 google_breakpad::PageAllocator allocator; | |
| 393 const size_t log_path_len = my_strlen(minidump.path()); | |
| 394 char* log_path = reinterpret_cast<char*>(allocator.Alloc(log_path_len + 1)); | |
| 395 my_memcpy(log_path, minidump.path(), log_path_len); | |
| 396 my_memcpy(log_path + log_path_len - 4, ".log", 4); | |
| 397 log_path[log_path_len] = '\0'; | |
| 398 info.log_filename = log_path; | |
| 399 #endif | |
| 375 info.process_type = "browser"; | 400 info.process_type = "browser"; |
| 376 info.process_type_length = 7; | 401 info.process_type_length = 7; |
| 377 info.crash_url = NULL; | 402 info.crash_url = NULL; |
| 378 info.crash_url_length = 0; | 403 info.crash_url_length = 0; |
| 379 info.guid = child_process_logging::g_client_id; | 404 info.guid = child_process_logging::g_client_id; |
| 380 info.guid_length = my_strlen(child_process_logging::g_client_id); | 405 info.guid_length = my_strlen(child_process_logging::g_client_id); |
| 381 info.distro = base::g_linux_distro; | 406 info.distro = base::g_linux_distro; |
| 382 info.distro_length = my_strlen(base::g_linux_distro); | 407 info.distro_length = my_strlen(base::g_linux_distro); |
| 383 info.upload = upload; | 408 info.upload = upload; |
| 384 info.process_start_time = g_process_start_time; | 409 info.process_start_time = g_process_start_time; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 397 | 422 |
| 398 #if !defined(OS_ANDROID) | 423 #if !defined(OS_ANDROID) |
| 399 // Wrapper function, do not add more code here. | 424 // Wrapper function, do not add more code here. |
| 400 bool CrashDoneUpload(const MinidumpDescriptor& minidump, | 425 bool CrashDoneUpload(const MinidumpDescriptor& minidump, |
| 401 void* context, | 426 void* context, |
| 402 bool succeeded) { | 427 bool succeeded) { |
| 403 return CrashDone(minidump, true, succeeded); | 428 return CrashDone(minidump, true, succeeded); |
| 404 } | 429 } |
| 405 #endif | 430 #endif |
| 406 | 431 |
| 432 #if defined(ADDRESS_SANITIZER) | |
| 433 extern "C" | |
| 434 void __asan_set_error_report_callback(void (*cb)(const char*)); | |
| 435 | |
| 436 extern "C" | |
| 437 void AsanLinuxBreakpadCallback(const char* report) { | |
| 438 g_asan_report_str = const_cast<char*>(report); | |
|
Lei Zhang
2012/08/21 18:35:17
nit: Can we make |g_asan_report_str| const char an
Alexander Potapenko
2012/08/22 12:15:08
Ok. This however has introduced a const_cast below
Lei Zhang
2012/08/22 18:41:55
Blah.
| |
| 439 // Send minidump here. | |
| 440 g_breakpad->SimulateSignalDelivery(9); | |
|
Lei Zhang
2012/08/21 18:35:17
nit: Can we use a SIGKILL constant from signal.h h
Alexander Potapenko
2012/08/22 12:15:08
Done.
| |
| 441 } | |
| 442 #endif | |
| 443 | |
| 407 void EnableCrashDumping(bool unattended) { | 444 void EnableCrashDumping(bool unattended) { |
| 408 g_is_crash_reporter_enabled = true; | 445 g_is_crash_reporter_enabled = true; |
| 409 | 446 |
| 410 FilePath tmp_path("/tmp"); | 447 FilePath tmp_path("/tmp"); |
| 411 PathService::Get(base::DIR_TEMP, &tmp_path); | 448 PathService::Get(base::DIR_TEMP, &tmp_path); |
| 412 | 449 |
| 413 FilePath dumps_path(tmp_path); | 450 FilePath dumps_path(tmp_path); |
| 414 if (PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path)) { | 451 if (PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path)) { |
| 415 FilePath logfile = | 452 FilePath logfile = |
| 416 dumps_path.AppendASCII(CrashUploadList::kReporterLogFilename); | 453 dumps_path.AppendASCII(CrashUploadList::kReporterLogFilename); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 476 char b; // Dummy variable for sys_read below. | 513 char b; // Dummy variable for sys_read below. |
| 477 const char* b_addr = &b; // Get the address of |b| so we can create the | 514 const char* b_addr = &b; // Get the address of |b| so we can create the |
| 478 // expected /proc/[pid]/syscall content in the | 515 // expected /proc/[pid]/syscall content in the |
| 479 // browser to convert namespace tids. | 516 // browser to convert namespace tids. |
| 480 | 517 |
| 481 // The length of the control message: | 518 // The length of the control message: |
| 482 static const unsigned kControlMsgSize = sizeof(fds); | 519 static const unsigned kControlMsgSize = sizeof(fds); |
| 483 static const unsigned kControlMsgSpaceSize = CMSG_SPACE(kControlMsgSize); | 520 static const unsigned kControlMsgSpaceSize = CMSG_SPACE(kControlMsgSize); |
| 484 static const unsigned kControlMsgLenSize = CMSG_LEN(kControlMsgSize); | 521 static const unsigned kControlMsgLenSize = CMSG_LEN(kControlMsgSize); |
| 485 | 522 |
| 523 #if !defined(ADDRESS_SANITIZER) | |
| 486 const size_t kIovSize = 8; | 524 const size_t kIovSize = 8; |
| 525 #else | |
| 526 // Additional field to pass the AddressSanitizer log to the crash handler. | |
| 527 const size_t kIovSize = 9; | |
| 528 #endif | |
| 487 struct kernel_msghdr msg; | 529 struct kernel_msghdr msg; |
| 488 my_memset(&msg, 0, sizeof(struct kernel_msghdr)); | 530 my_memset(&msg, 0, sizeof(struct kernel_msghdr)); |
| 489 struct kernel_iovec iov[kIovSize]; | 531 struct kernel_iovec iov[kIovSize]; |
| 490 iov[0].iov_base = const_cast<void*>(crash_context); | 532 iov[0].iov_base = const_cast<void*>(crash_context); |
| 491 iov[0].iov_len = crash_context_size; | 533 iov[0].iov_len = crash_context_size; |
| 492 iov[1].iov_base = guid; | 534 iov[1].iov_base = guid; |
| 493 iov[1].iov_len = kGuidSize + 1; | 535 iov[1].iov_len = kGuidSize + 1; |
| 494 iov[2].iov_base = crash_url; | 536 iov[2].iov_base = crash_url; |
| 495 iov[2].iov_len = kMaxActiveURLSize + 1; | 537 iov[2].iov_len = kMaxActiveURLSize + 1; |
| 496 iov[3].iov_base = distro; | 538 iov[3].iov_base = distro; |
| 497 iov[3].iov_len = kDistroSize + 1; | 539 iov[3].iov_len = kDistroSize + 1; |
| 498 iov[4].iov_base = &b_addr; | 540 iov[4].iov_base = &b_addr; |
| 499 iov[4].iov_len = sizeof(b_addr); | 541 iov[4].iov_len = sizeof(b_addr); |
| 500 iov[5].iov_base = &fds[0]; | 542 iov[5].iov_base = &fds[0]; |
| 501 iov[5].iov_len = sizeof(fds[0]); | 543 iov[5].iov_len = sizeof(fds[0]); |
| 502 iov[6].iov_base = &g_process_start_time; | 544 iov[6].iov_base = &g_process_start_time; |
| 503 iov[6].iov_len = sizeof(g_process_start_time); | 545 iov[6].iov_len = sizeof(g_process_start_time); |
| 504 iov[7].iov_base = &base::g_oom_size; | 546 iov[7].iov_base = &base::g_oom_size; |
| 505 iov[7].iov_len = sizeof(base::g_oom_size); | 547 iov[7].iov_len = sizeof(base::g_oom_size); |
| 548 #if defined(ADDRESS_SANITIZER) | |
| 549 iov[8].iov_base = g_asan_report_str; | |
| 550 iov[8].iov_len = kMaxAsanReportSize + 1; | |
| 551 #endif | |
| 506 | 552 |
| 507 msg.msg_iov = iov; | 553 msg.msg_iov = iov; |
| 508 msg.msg_iovlen = kIovSize; | 554 msg.msg_iovlen = kIovSize; |
| 509 char cmsg[kControlMsgSpaceSize]; | 555 char cmsg[kControlMsgSpaceSize]; |
| 510 my_memset(cmsg, 0, kControlMsgSpaceSize); | 556 my_memset(cmsg, 0, kControlMsgSpaceSize); |
| 511 msg.msg_control = cmsg; | 557 msg.msg_control = cmsg; |
| 512 msg.msg_controllen = sizeof(cmsg); | 558 msg.msg_controllen = sizeof(cmsg); |
| 513 | 559 |
| 514 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); | 560 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); |
| 515 hdr->cmsg_level = SOL_SOCKET; | 561 hdr->cmsg_level = SOL_SOCKET; |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 544 NULL, | 590 NULL, |
| 545 NULL, | 591 NULL, |
| 546 reinterpret_cast<void*>(fd), // Param passed to the crash handler. | 592 reinterpret_cast<void*>(fd), // Param passed to the crash handler. |
| 547 true, | 593 true, |
| 548 -1); | 594 -1); |
| 549 g_breakpad->set_crash_handler(NonBrowserCrashHandler); | 595 g_breakpad->set_crash_handler(NonBrowserCrashHandler); |
| 550 } | 596 } |
| 551 | 597 |
| 552 } // namespace | 598 } // namespace |
| 553 | 599 |
| 554 void HandleCrashDump(const BreakpadInfo& info) { | 600 void LoadDataFromFile(google_breakpad::PageAllocator& allocator, |
| 601 const BreakpadInfo& info, int* fd, | |
| 602 uint8_t** file_data, size_t* size, | |
| 603 const char* filename) { | |
|
Lei Zhang
2012/08/21 18:35:17
nit: Can we move |filename| in front of the out pa
Alexander Potapenko
2012/08/22 12:15:08
Done.
| |
| 555 // WARNING: this code runs in a compromised context. It may not call into | 604 // WARNING: this code runs in a compromised context. It may not call into |
| 556 // libc nor allocate memory normally. | 605 // libc nor allocate memory normally. |
| 606 *fd = sys_open(filename, O_RDONLY, 0); | |
| 607 *size = 0; | |
| 557 | 608 |
| 558 const int dumpfd = sys_open(info.filename, O_RDONLY, 0); | 609 if (*fd < 0) { |
| 559 if (dumpfd < 0) { | |
| 560 static const char msg[] = "Cannot upload crash dump: failed to open\n"; | 610 static const char msg[] = "Cannot upload crash dump: failed to open\n"; |
| 561 WriteLog(msg, sizeof(msg)); | 611 WriteLog(msg, sizeof(msg)); |
| 562 return; | 612 return; |
| 563 } | 613 } |
| 564 STAT_STRUCT st; | 614 STAT_STRUCT st; |
| 565 if (FSTAT_FUNC(dumpfd, &st) != 0) { | 615 if (FSTAT_FUNC(*fd, &st) != 0) { |
| 566 static const char msg[] = "Cannot upload crash dump: stat failed\n"; | 616 static const char msg[] = "Cannot upload crash dump: stat failed\n"; |
| 567 WriteLog(msg, sizeof(msg)); | 617 WriteLog(msg, sizeof(msg)); |
| 568 IGNORE_RET(sys_close(dumpfd)); | 618 IGNORE_RET(sys_close(*fd)); |
| 569 return; | 619 return; |
| 570 } | 620 } |
| 571 | 621 |
| 572 google_breakpad::PageAllocator allocator; | 622 *file_data = reinterpret_cast<uint8_t*>(allocator.Alloc(st.st_size)); |
| 573 | 623 if (!(*file_data)) { |
| 574 uint8_t* dump_data = reinterpret_cast<uint8_t*>(allocator.Alloc(st.st_size)); | |
| 575 if (!dump_data) { | |
| 576 static const char msg[] = "Cannot upload crash dump: cannot alloc\n"; | 624 static const char msg[] = "Cannot upload crash dump: cannot alloc\n"; |
| 577 WriteLog(msg, sizeof(msg)); | 625 WriteLog(msg, sizeof(msg)); |
| 578 IGNORE_RET(sys_close(dumpfd)); | 626 IGNORE_RET(sys_close(*fd)); |
| 579 return; | 627 return; |
| 580 } | 628 } |
| 629 my_memset(*file_data, 0xf, st.st_size); | |
| 581 | 630 |
| 582 sys_read(dumpfd, dump_data, st.st_size); | 631 *size = st.st_size; |
| 583 IGNORE_RET(sys_close(dumpfd)); | 632 sys_read(*fd, *file_data, *size); |
| 633 IGNORE_RET(sys_close(*fd)); | |
| 634 } | |
| 635 | |
| 636 void HandleCrashDump(const BreakpadInfo& info) { | |
| 637 int dumpfd; | |
| 638 size_t dump_size; | |
| 639 uint8_t *dump_data; | |
| 640 google_breakpad::PageAllocator allocator; | |
| 641 LoadDataFromFile(allocator, info, &dumpfd, &dump_data, &dump_size, | |
| 642 info.filename); | |
| 643 #if defined(ADDRESS_SANITIZER) | |
| 644 int logfd; | |
| 645 size_t log_size; | |
| 646 uint8_t *log_data; | |
| 647 // Load the AddressSanitizer log into log_data. | |
| 648 LoadDataFromFile(allocator, info, &logfd, &log_data, &log_size, | |
| 649 info.log_filename); | |
| 650 #endif | |
| 584 | 651 |
| 585 // We need to build a MIME block for uploading to the server. Since we are | 652 // We need to build a MIME block for uploading to the server. Since we are |
| 586 // going to fork and run wget, it needs to be written to a temp file. | 653 // going to fork and run wget, it needs to be written to a temp file. |
| 587 | |
| 588 const int ufd = sys_open("/dev/urandom", O_RDONLY, 0); | 654 const int ufd = sys_open("/dev/urandom", O_RDONLY, 0); |
| 589 if (ufd < 0) { | 655 if (ufd < 0) { |
| 590 static const char msg[] = "Cannot upload crash dump because /dev/urandom" | 656 static const char msg[] = "Cannot upload crash dump because /dev/urandom" |
| 591 " is missing\n"; | 657 " is missing\n"; |
| 592 WriteLog(msg, sizeof(msg) - 1); | 658 WriteLog(msg, sizeof(msg) - 1); |
| 593 return; | 659 return; |
| 594 } | 660 } |
| 595 | 661 |
| 596 static const char temp_file_template[] = | 662 static const char temp_file_template[] = |
| 597 "/tmp/chromium-upload-XXXXXXXXXXXXXXXX"; | 663 "/tmp/chromium-upload-XXXXXXXXXXXXXXXX"; |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 909 char oom_size_str[kUint64StringSize]; | 975 char oom_size_str[kUint64StringSize]; |
| 910 const unsigned oom_size_len = my_uint64_len(info.oom_size); | 976 const unsigned oom_size_len = my_uint64_len(info.oom_size); |
| 911 my_uint64tos(oom_size_str, info.oom_size, oom_size_len); | 977 my_uint64tos(oom_size_str, info.oom_size, oom_size_len); |
| 912 static const char oom_size_msg[] = "oom-size"; | 978 static const char oom_size_msg[] = "oom-size"; |
| 913 writer.AddPairData(oom_size_msg, sizeof(oom_size_msg) - 1, | 979 writer.AddPairData(oom_size_msg, sizeof(oom_size_msg) - 1, |
| 914 oom_size_str, oom_size_len); | 980 oom_size_str, oom_size_len); |
| 915 writer.AddBoundary(); | 981 writer.AddBoundary(); |
| 916 writer.Flush(); | 982 writer.Flush(); |
| 917 } | 983 } |
| 918 | 984 |
| 919 writer.AddFileDump(dump_data, st.st_size); | 985 writer.AddFileContents(g_dump_msg, dump_data, dump_size); |
| 986 #if defined(ADDRESS_SANITIZER) | |
| 987 // Append a multipart boundary and the contents of the AddressSanitizer log. | |
| 988 writer.AddBoundary(); | |
| 989 writer.AddFileContents(g_log_msg, log_data, log_size); | |
| 990 #endif | |
| 920 writer.AddEnd(); | 991 writer.AddEnd(); |
| 921 writer.Flush(); | 992 writer.Flush(); |
| 922 | 993 |
| 923 IGNORE_RET(sys_close(temp_file_fd)); | 994 IGNORE_RET(sys_close(temp_file_fd)); |
| 924 | 995 |
| 925 #if defined(OS_ANDROID) | 996 #if defined(OS_ANDROID) |
| 926 __android_log_write(ANDROID_LOG_WARN, | 997 __android_log_write(ANDROID_LOG_WARN, |
| 927 kGoogleBreakpad, | 998 kGoogleBreakpad, |
| 928 "Output crash dump file:"); | 999 "Output crash dump file:"); |
| 929 __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, info.filename); | 1000 __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, info.filename); |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1090 } | 1161 } |
| 1091 if (sys_waitpid(wget_child, NULL, WNOHANG) == 0) { | 1162 if (sys_waitpid(wget_child, NULL, WNOHANG) == 0) { |
| 1092 // Wget process is still around, kill it. | 1163 // Wget process is still around, kill it. |
| 1093 sys_kill(wget_child, SIGKILL); | 1164 sys_kill(wget_child, SIGKILL); |
| 1094 } | 1165 } |
| 1095 } | 1166 } |
| 1096 } | 1167 } |
| 1097 | 1168 |
| 1098 // Helper process. | 1169 // Helper process. |
| 1099 IGNORE_RET(sys_unlink(info.filename)); | 1170 IGNORE_RET(sys_unlink(info.filename)); |
| 1171 #if defined(ADDRESS_SANITIZER) | |
| 1172 IGNORE_RET(sys_unlink(info.log_filename)); | |
| 1173 #endif | |
| 1100 IGNORE_RET(sys_unlink(temp_file)); | 1174 IGNORE_RET(sys_unlink(temp_file)); |
| 1101 sys__exit(0); | 1175 sys__exit(0); |
| 1102 } | 1176 } |
| 1103 | 1177 |
| 1104 // Main browser process. | 1178 // Main browser process. |
| 1105 if (child <= 0) | 1179 if (child <= 0) |
| 1106 return; | 1180 return; |
| 1107 (void) HANDLE_EINTR(sys_waitpid(child, NULL, 0)); | 1181 (void) HANDLE_EINTR(sys_waitpid(child, NULL, 0)); |
| 1108 } | 1182 } |
| 1109 | 1183 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1151 } | 1225 } |
| 1152 | 1226 |
| 1153 // Set the base process start time value. | 1227 // Set the base process start time value. |
| 1154 struct timeval tv; | 1228 struct timeval tv; |
| 1155 if (!gettimeofday(&tv, NULL)) | 1229 if (!gettimeofday(&tv, NULL)) |
| 1156 g_process_start_time = timeval_to_ms(&tv); | 1230 g_process_start_time = timeval_to_ms(&tv); |
| 1157 else | 1231 else |
| 1158 g_process_start_time = 0; | 1232 g_process_start_time = 0; |
| 1159 | 1233 |
| 1160 logging::SetDumpWithoutCrashingFunction(&DumpProcess); | 1234 logging::SetDumpWithoutCrashingFunction(&DumpProcess); |
| 1235 #if defined(ADDRESS_SANITIZER) | |
| 1236 // Register the callback for AddressSanitizer error reporting. | |
| 1237 __asan_set_error_report_callback(AsanLinuxBreakpadCallback); | |
| 1238 #endif | |
| 1161 } | 1239 } |
| 1162 | 1240 |
| 1163 bool IsCrashReporterEnabled() { | 1241 bool IsCrashReporterEnabled() { |
| 1164 return g_is_crash_reporter_enabled; | 1242 return g_is_crash_reporter_enabled; |
| 1165 } | 1243 } |
| OLD | NEW |