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 |