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 |
11 #include <fcntl.h> | 11 #include <fcntl.h> |
12 #include <poll.h> | 12 #include <poll.h> |
| 13 #include <signal.h> |
13 #include <stdlib.h> | 14 #include <stdlib.h> |
14 #include <sys/socket.h> | 15 #include <sys/socket.h> |
15 #include <sys/time.h> | 16 #include <sys/time.h> |
16 #include <sys/types.h> | 17 #include <sys/types.h> |
17 #include <sys/wait.h> | 18 #include <sys/wait.h> |
18 #include <sys/uio.h> | 19 #include <sys/uio.h> |
19 #include <time.h> | 20 #include <time.h> |
20 #include <unistd.h> | 21 #include <unistd.h> |
21 | 22 |
22 #include <algorithm> | 23 #include <algorithm> |
(...skipping 24 matching lines...) Expand all Loading... |
47 #include <android/log.h> | 48 #include <android/log.h> |
48 #include <sys/stat.h> | 49 #include <sys/stat.h> |
49 | 50 |
50 #include "base/android/build_info.h" | 51 #include "base/android/build_info.h" |
51 #include "base/android/path_utils.h" | 52 #include "base/android/path_utils.h" |
52 #include "third_party/lss/linux_syscall_support.h" | 53 #include "third_party/lss/linux_syscall_support.h" |
53 #else | 54 #else |
54 #include "sandbox/linux/seccomp-legacy/linux_syscall_support.h" | 55 #include "sandbox/linux/seccomp-legacy/linux_syscall_support.h" |
55 #endif | 56 #endif |
56 | 57 |
| 58 #if defined(ADDRESS_SANITIZER) |
| 59 #include <ucontext.h> // for getcontext(). |
| 60 #endif |
| 61 |
57 #if defined(OS_ANDROID) | 62 #if defined(OS_ANDROID) |
58 #define STAT_STRUCT struct stat | 63 #define STAT_STRUCT struct stat |
59 #define FSTAT_FUNC fstat | 64 #define FSTAT_FUNC fstat |
60 #else | 65 #else |
61 #define STAT_STRUCT struct kernel_stat | 66 #define STAT_STRUCT struct kernel_stat |
62 #define FSTAT_FUNC sys_fstat | 67 #define FSTAT_FUNC sys_fstat |
63 #endif | 68 #endif |
64 | 69 |
65 // Some versions of gcc are prone to warn about unused return values. In cases | 70 // 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 | 71 // 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 | 72 // can do when a call fails, we mark the return code as ignored. This avoids |
68 // spurious compiler warnings. | 73 // spurious compiler warnings. |
69 #define IGNORE_RET(x) do { if (x); } while (0) | 74 #define IGNORE_RET(x) do { if (x); } while (0) |
70 | 75 |
71 using google_breakpad::ExceptionHandler; | 76 using google_breakpad::ExceptionHandler; |
72 using google_breakpad::MinidumpDescriptor; | 77 using google_breakpad::MinidumpDescriptor; |
73 | 78 |
74 namespace { | 79 namespace { |
75 | 80 |
| 81 #if !defined(ADDRESS_SANITIZER) |
76 const char kUploadURL[] = "https://clients2.google.com/cr/report"; | 82 const char kUploadURL[] = "https://clients2.google.com/cr/report"; |
| 83 #else |
| 84 // AddressSanitizer should currently upload the crash reports to the staging |
| 85 // crash server. |
| 86 const char kUploadURL[] = "https://clients2.google.com/cr/staging_report"; |
| 87 #endif |
77 | 88 |
78 bool g_is_crash_reporter_enabled = false; | 89 bool g_is_crash_reporter_enabled = false; |
79 uint64_t g_process_start_time = 0; | 90 uint64_t g_process_start_time = 0; |
80 char* g_crash_log_path = NULL; | 91 char* g_crash_log_path = NULL; |
81 ExceptionHandler* g_breakpad = NULL; | 92 ExceptionHandler* g_breakpad = NULL; |
| 93 #if defined(ADDRESS_SANITIZER) |
| 94 const char* g_asan_report_str = NULL; |
| 95 #endif |
82 | 96 |
83 // Writes the value |v| as 16 hex characters to the memory pointed at by | 97 // Writes the value |v| as 16 hex characters to the memory pointed at by |
84 // |output|. | 98 // |output|. |
85 void write_uint64_hex(char* output, uint64_t v) { | 99 void write_uint64_hex(char* output, uint64_t v) { |
86 static const char hextable[] = "0123456789abcdef"; | 100 static const char hextable[] = "0123456789abcdef"; |
87 | 101 |
88 for (int i = 15; i >= 0; --i) { | 102 for (int i = 15; i >= 0; --i) { |
89 output[i] = hextable[v & 15]; | 103 output[i] = hextable[v & 15]; |
90 v >>= 4; | 104 v >>= 4; |
91 } | 105 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 return ret; | 178 return ret; |
165 } | 179 } |
166 #endif | 180 #endif |
167 | 181 |
168 // MIME substrings. | 182 // MIME substrings. |
169 const char g_rn[] = "\r\n"; | 183 const char g_rn[] = "\r\n"; |
170 const char g_form_data_msg[] = "Content-Disposition: form-data; name=\""; | 184 const char g_form_data_msg[] = "Content-Disposition: form-data; name=\""; |
171 const char g_quote_msg[] = "\""; | 185 const char g_quote_msg[] = "\""; |
172 const char g_dashdash_msg[] = "--"; | 186 const char g_dashdash_msg[] = "--"; |
173 const char g_dump_msg[] = "upload_file_minidump\"; filename=\"dump\""; | 187 const char g_dump_msg[] = "upload_file_minidump\"; filename=\"dump\""; |
| 188 #if defined(ADDRESS_SANITIZER) |
| 189 const char g_log_msg[] = "upload_file_log\"; filename=\"log\""; |
| 190 #endif |
174 const char g_content_type_msg[] = "Content-Type: application/octet-stream"; | 191 const char g_content_type_msg[] = "Content-Type: application/octet-stream"; |
175 | 192 |
176 // MimeWriter manages an iovec for writing MIMEs to a file. | 193 // MimeWriter manages an iovec for writing MIMEs to a file. |
177 class MimeWriter { | 194 class MimeWriter { |
178 public: | 195 public: |
179 static const int kIovCapacity = 30; | 196 static const int kIovCapacity = 30; |
180 static const size_t kMaxCrashChunkSize = 64; | 197 static const size_t kMaxCrashChunkSize = 64; |
181 | 198 |
182 MimeWriter(int fd, const char* const mime_boundary); | 199 MimeWriter(int fd, const char* const mime_boundary); |
183 ~MimeWriter(); | 200 ~MimeWriter(); |
(...skipping 19 matching lines...) Expand all Loading... |
203 // Append key/value pair, splitting value into chunks no larger than | 220 // Append key/value pair, splitting value into chunks no larger than |
204 // |chunk_size|. |chunk_size| cannot be greater than |kMaxCrashChunkSize|. | 221 // |chunk_size|. |chunk_size| cannot be greater than |kMaxCrashChunkSize|. |
205 // The msg_type string will have a counter suffix to distinguish each chunk. | 222 // The msg_type string will have a counter suffix to distinguish each chunk. |
206 void AddPairDataInChunks(const char* msg_type, | 223 void AddPairDataInChunks(const char* msg_type, |
207 size_t msg_type_size, | 224 size_t msg_type_size, |
208 const char* msg_data, | 225 const char* msg_data, |
209 size_t msg_data_size, | 226 size_t msg_data_size, |
210 size_t chunk_size, | 227 size_t chunk_size, |
211 bool strip_trailing_spaces); | 228 bool strip_trailing_spaces); |
212 | 229 |
213 // Add binary file dump. Currently this is only done once, so the name is | 230 // Add binary file contents to be uploaded with the specified filename. |
214 // fixed. | 231 void AddFileContents(const char* filename_msg, |
215 void AddFileDump(uint8_t* file_data, | 232 uint8_t* file_data, |
216 size_t file_size); | 233 size_t file_size); |
217 | 234 |
218 // Flush any pending iovecs to the output file. | 235 // Flush any pending iovecs to the output file. |
219 void Flush() { | 236 void Flush() { |
220 IGNORE_RET(sys_writev(fd_, iov_, iov_index_)); | 237 IGNORE_RET(sys_writev(fd_, iov_, iov_index_)); |
221 iov_index_ = 0; | 238 iov_index_ = 0; |
222 } | 239 } |
223 | 240 |
224 private: | 241 private: |
225 void AddItem(const void* base, size_t size); | 242 void AddItem(const void* base, size_t size); |
226 // Minor performance trade-off for easier-to-maintain code. | 243 // Minor performance trade-off for easier-to-maintain code. |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 } | 322 } |
306 AddString(g_rn); | 323 AddString(g_rn); |
307 AddBoundary(); | 324 AddBoundary(); |
308 Flush(); | 325 Flush(); |
309 | 326 |
310 done += chunk_len; | 327 done += chunk_len; |
311 msg_length -= chunk_len; | 328 msg_length -= chunk_len; |
312 } | 329 } |
313 } | 330 } |
314 | 331 |
315 void MimeWriter::AddFileDump(uint8_t* file_data, | 332 void MimeWriter::AddFileContents(const char* filename_msg, uint8_t* file_data, |
316 size_t file_size) { | 333 size_t file_size) { |
317 AddString(g_form_data_msg); | 334 AddString(g_form_data_msg); |
318 AddString(g_dump_msg); | 335 AddString(filename_msg); |
319 AddString(g_rn); | 336 AddString(g_rn); |
320 AddString(g_content_type_msg); | 337 AddString(g_content_type_msg); |
321 AddString(g_rn); | 338 AddString(g_rn); |
322 AddString(g_rn); | 339 AddString(g_rn); |
323 AddItem(file_data, file_size); | 340 AddItem(file_data, file_size); |
324 AddString(g_rn); | 341 AddString(g_rn); |
325 } | 342 } |
326 | 343 |
327 void MimeWriter::AddItem(const void* base, size_t size) { | 344 void MimeWriter::AddItem(const void* base, size_t size) { |
328 // Check if the iovec is full and needs to be flushed to output file. | 345 // 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) { | 382 const bool succeeded) { |
366 // WARNING: this code runs in a compromised context. It may not call into | 383 // WARNING: this code runs in a compromised context. It may not call into |
367 // libc nor allocate memory normally. | 384 // libc nor allocate memory normally. |
368 if (!succeeded) | 385 if (!succeeded) |
369 return false; | 386 return false; |
370 | 387 |
371 DCHECK(!minidump.IsFD()); | 388 DCHECK(!minidump.IsFD()); |
372 | 389 |
373 BreakpadInfo info; | 390 BreakpadInfo info; |
374 info.filename = minidump.path(); | 391 info.filename = minidump.path(); |
| 392 #if defined(ADDRESS_SANITIZER) |
| 393 google_breakpad::PageAllocator allocator; |
| 394 const size_t log_path_len = my_strlen(minidump.path()); |
| 395 char* log_path = reinterpret_cast<char*>(allocator.Alloc(log_path_len + 1)); |
| 396 my_memcpy(log_path, minidump.path(), log_path_len); |
| 397 my_memcpy(log_path + log_path_len - 4, ".log", 4); |
| 398 log_path[log_path_len] = '\0'; |
| 399 info.log_filename = log_path; |
| 400 #endif |
375 info.process_type = "browser"; | 401 info.process_type = "browser"; |
376 info.process_type_length = 7; | 402 info.process_type_length = 7; |
377 info.crash_url = NULL; | 403 info.crash_url = NULL; |
378 info.crash_url_length = 0; | 404 info.crash_url_length = 0; |
379 info.guid = child_process_logging::g_client_id; | 405 info.guid = child_process_logging::g_client_id; |
380 info.guid_length = my_strlen(child_process_logging::g_client_id); | 406 info.guid_length = my_strlen(child_process_logging::g_client_id); |
381 info.distro = base::g_linux_distro; | 407 info.distro = base::g_linux_distro; |
382 info.distro_length = my_strlen(base::g_linux_distro); | 408 info.distro_length = my_strlen(base::g_linux_distro); |
383 info.upload = upload; | 409 info.upload = upload; |
384 info.process_start_time = g_process_start_time; | 410 info.process_start_time = g_process_start_time; |
(...skipping 12 matching lines...) Expand all Loading... |
397 | 423 |
398 #if !defined(OS_ANDROID) | 424 #if !defined(OS_ANDROID) |
399 // Wrapper function, do not add more code here. | 425 // Wrapper function, do not add more code here. |
400 bool CrashDoneUpload(const MinidumpDescriptor& minidump, | 426 bool CrashDoneUpload(const MinidumpDescriptor& minidump, |
401 void* context, | 427 void* context, |
402 bool succeeded) { | 428 bool succeeded) { |
403 return CrashDone(minidump, true, succeeded); | 429 return CrashDone(minidump, true, succeeded); |
404 } | 430 } |
405 #endif | 431 #endif |
406 | 432 |
| 433 #if defined(ADDRESS_SANITIZER) |
| 434 extern "C" |
| 435 void __asan_set_error_report_callback(void (*cb)(const char*)); |
| 436 |
| 437 extern "C" |
| 438 void AsanLinuxBreakpadCallback(const char* report) { |
| 439 g_asan_report_str = report; |
| 440 // Send minidump here. |
| 441 g_breakpad->SimulateSignalDelivery(SIGKILL); |
| 442 } |
| 443 #endif |
| 444 |
407 void EnableCrashDumping(bool unattended) { | 445 void EnableCrashDumping(bool unattended) { |
408 g_is_crash_reporter_enabled = true; | 446 g_is_crash_reporter_enabled = true; |
409 | 447 |
410 FilePath tmp_path("/tmp"); | 448 FilePath tmp_path("/tmp"); |
411 PathService::Get(base::DIR_TEMP, &tmp_path); | 449 PathService::Get(base::DIR_TEMP, &tmp_path); |
412 | 450 |
413 FilePath dumps_path(tmp_path); | 451 FilePath dumps_path(tmp_path); |
414 if (PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path)) { | 452 if (PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path)) { |
415 FilePath logfile = | 453 FilePath logfile = |
416 dumps_path.AppendASCII(CrashUploadList::kReporterLogFilename); | 454 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. | 514 char b; // Dummy variable for sys_read below. |
477 const char* b_addr = &b; // Get the address of |b| so we can create the | 515 const char* b_addr = &b; // Get the address of |b| so we can create the |
478 // expected /proc/[pid]/syscall content in the | 516 // expected /proc/[pid]/syscall content in the |
479 // browser to convert namespace tids. | 517 // browser to convert namespace tids. |
480 | 518 |
481 // The length of the control message: | 519 // The length of the control message: |
482 static const unsigned kControlMsgSize = sizeof(fds); | 520 static const unsigned kControlMsgSize = sizeof(fds); |
483 static const unsigned kControlMsgSpaceSize = CMSG_SPACE(kControlMsgSize); | 521 static const unsigned kControlMsgSpaceSize = CMSG_SPACE(kControlMsgSize); |
484 static const unsigned kControlMsgLenSize = CMSG_LEN(kControlMsgSize); | 522 static const unsigned kControlMsgLenSize = CMSG_LEN(kControlMsgSize); |
485 | 523 |
| 524 #if !defined(ADDRESS_SANITIZER) |
486 const size_t kIovSize = 8; | 525 const size_t kIovSize = 8; |
| 526 #else |
| 527 // Additional field to pass the AddressSanitizer log to the crash handler. |
| 528 const size_t kIovSize = 9; |
| 529 #endif |
487 struct kernel_msghdr msg; | 530 struct kernel_msghdr msg; |
488 my_memset(&msg, 0, sizeof(struct kernel_msghdr)); | 531 my_memset(&msg, 0, sizeof(struct kernel_msghdr)); |
489 struct kernel_iovec iov[kIovSize]; | 532 struct kernel_iovec iov[kIovSize]; |
490 iov[0].iov_base = const_cast<void*>(crash_context); | 533 iov[0].iov_base = const_cast<void*>(crash_context); |
491 iov[0].iov_len = crash_context_size; | 534 iov[0].iov_len = crash_context_size; |
492 iov[1].iov_base = guid; | 535 iov[1].iov_base = guid; |
493 iov[1].iov_len = kGuidSize + 1; | 536 iov[1].iov_len = kGuidSize + 1; |
494 iov[2].iov_base = crash_url; | 537 iov[2].iov_base = crash_url; |
495 iov[2].iov_len = kMaxActiveURLSize + 1; | 538 iov[2].iov_len = kMaxActiveURLSize + 1; |
496 iov[3].iov_base = distro; | 539 iov[3].iov_base = distro; |
497 iov[3].iov_len = kDistroSize + 1; | 540 iov[3].iov_len = kDistroSize + 1; |
498 iov[4].iov_base = &b_addr; | 541 iov[4].iov_base = &b_addr; |
499 iov[4].iov_len = sizeof(b_addr); | 542 iov[4].iov_len = sizeof(b_addr); |
500 iov[5].iov_base = &fds[0]; | 543 iov[5].iov_base = &fds[0]; |
501 iov[5].iov_len = sizeof(fds[0]); | 544 iov[5].iov_len = sizeof(fds[0]); |
502 iov[6].iov_base = &g_process_start_time; | 545 iov[6].iov_base = &g_process_start_time; |
503 iov[6].iov_len = sizeof(g_process_start_time); | 546 iov[6].iov_len = sizeof(g_process_start_time); |
504 iov[7].iov_base = &base::g_oom_size; | 547 iov[7].iov_base = &base::g_oom_size; |
505 iov[7].iov_len = sizeof(base::g_oom_size); | 548 iov[7].iov_len = sizeof(base::g_oom_size); |
| 549 #if defined(ADDRESS_SANITIZER) |
| 550 iov[8].iov_base = const_cast<char*>(g_asan_report_str); |
| 551 iov[8].iov_len = kMaxAsanReportSize + 1; |
| 552 #endif |
506 | 553 |
507 msg.msg_iov = iov; | 554 msg.msg_iov = iov; |
508 msg.msg_iovlen = kIovSize; | 555 msg.msg_iovlen = kIovSize; |
509 char cmsg[kControlMsgSpaceSize]; | 556 char cmsg[kControlMsgSpaceSize]; |
510 my_memset(cmsg, 0, kControlMsgSpaceSize); | 557 my_memset(cmsg, 0, kControlMsgSpaceSize); |
511 msg.msg_control = cmsg; | 558 msg.msg_control = cmsg; |
512 msg.msg_controllen = sizeof(cmsg); | 559 msg.msg_controllen = sizeof(cmsg); |
513 | 560 |
514 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); | 561 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); |
515 hdr->cmsg_level = SOL_SOCKET; | 562 hdr->cmsg_level = SOL_SOCKET; |
(...skipping 28 matching lines...) Expand all Loading... |
544 NULL, | 591 NULL, |
545 NULL, | 592 NULL, |
546 reinterpret_cast<void*>(fd), // Param passed to the crash handler. | 593 reinterpret_cast<void*>(fd), // Param passed to the crash handler. |
547 true, | 594 true, |
548 -1); | 595 -1); |
549 g_breakpad->set_crash_handler(NonBrowserCrashHandler); | 596 g_breakpad->set_crash_handler(NonBrowserCrashHandler); |
550 } | 597 } |
551 | 598 |
552 } // namespace | 599 } // namespace |
553 | 600 |
554 void HandleCrashDump(const BreakpadInfo& info) { | 601 void LoadDataFromFile(google_breakpad::PageAllocator& allocator, |
| 602 const BreakpadInfo& info, const char* filename, |
| 603 int* fd, uint8_t** file_data, size_t* size) { |
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, info.filename, |
| 642 &dumpfd, &dump_data, &dump_size); |
| 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, info.log_filename, |
| 649 &logfd, &log_data, &log_size); |
| 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 |