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_linuxish.h" | 9 #include "chrome/app/breakpad_linuxish.h" |
10 | 10 |
(...skipping 28 matching lines...) Expand all Loading... |
39 #include "chrome/common/chrome_paths.h" | 39 #include "chrome/common/chrome_paths.h" |
40 #include "chrome/common/chrome_switches.h" | 40 #include "chrome/common/chrome_switches.h" |
41 #include "chrome/common/chrome_version_info_posix.h" | 41 #include "chrome/common/chrome_version_info_posix.h" |
42 #include "chrome/common/env_vars.h" | 42 #include "chrome/common/env_vars.h" |
43 #include "chrome/common/logging_chrome.h" | 43 #include "chrome/common/logging_chrome.h" |
44 #include "content/common/chrome_descriptors.h" | 44 #include "content/common/chrome_descriptors.h" |
45 | 45 |
46 #if defined(OS_ANDROID) | 46 #if defined(OS_ANDROID) |
47 #include <android/log.h> | 47 #include <android/log.h> |
48 #include <sys/stat.h> | 48 #include <sys/stat.h> |
| 49 |
| 50 #include "base/android/build_info.h" |
49 #include "base/android/path_utils.h" | 51 #include "base/android/path_utils.h" |
50 #include "base/android/build_info.h" | |
51 #include "third_party/lss/linux_syscall_support.h" | 52 #include "third_party/lss/linux_syscall_support.h" |
52 #else | 53 #else |
53 #include "seccompsandbox/linux_syscall_support.h" | 54 #include "seccompsandbox/linux_syscall_support.h" |
54 #endif | 55 #endif |
55 | 56 |
| 57 #if defined(OS_ANDROID) |
| 58 #define STAT_STRUCT struct stat |
| 59 #define FSTAT_FUNC fstat |
| 60 #else |
| 61 #define STAT_STRUCT struct kernel_stat |
| 62 #define FSTAT_FUNC sys_fstat |
| 63 #endif |
| 64 |
56 #ifndef PR_SET_PTRACER | 65 #ifndef PR_SET_PTRACER |
57 #define PR_SET_PTRACER 0x59616d61 | 66 #define PR_SET_PTRACER 0x59616d61 |
58 #endif | 67 #endif |
59 | 68 |
60 // 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 |
61 // 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 |
62 // 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 |
63 // spurious compiler warnings. | 72 // spurious compiler warnings. |
64 #define IGNORE_RET(x) do { if (x); } while (0) | 73 #define IGNORE_RET(x) do { if (x); } while (0) |
65 | 74 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 *p++ = *src++; | 146 *p++ = *src++; |
138 i--; | 147 i--; |
139 } | 148 } |
140 while (i != 0) { | 149 while (i != 0) { |
141 *p++ = '\0'; | 150 *p++ = '\0'; |
142 i--; | 151 i--; |
143 } | 152 } |
144 return dst; | 153 return dst; |
145 } | 154 } |
146 | 155 |
147 static char* my_strncat(char *dest, const char *src, size_t len) { | 156 static char* my_strncat(char *dest, const char* src, size_t len) { |
148 char *ret = dest; | 157 char* ret = dest; |
149 while (*dest) | 158 while (*dest) |
150 dest++; | 159 dest++; |
151 while (len--) | 160 while (len--) |
152 if (!(*dest++ = *src++)) | 161 if (!(*dest++ = *src++)) |
153 return ret; | 162 return ret; |
154 *dest = 0; | 163 *dest = 0; |
155 return ret; | 164 return ret; |
156 } | 165 } |
157 #endif | 166 #endif |
158 | 167 |
159 namespace { | 168 namespace { |
160 | 169 |
161 // MIME substrings. | 170 // MIME substrings. |
162 static const char g_rn[] = "\r\n"; | 171 const char g_rn[] = "\r\n"; |
163 static const char g_form_data_msg[] = "Content-Disposition: form-data; name=\""; | 172 const char g_form_data_msg[] = "Content-Disposition: form-data; name=\""; |
164 static const char g_quote_msg[] = "\""; | 173 const char g_quote_msg[] = "\""; |
165 static const char g_dashdash_msg[] = "--"; | 174 const char g_dashdash_msg[] = "--"; |
166 static const char g_dump_msg[] = "upload_file_minidump\"; filename=\"dump\""; | 175 const char g_dump_msg[] = "upload_file_minidump\"; filename=\"dump\""; |
167 static const char g_content_type_msg[] = | 176 const char g_content_type_msg[] = "Content-Type: application/octet-stream"; |
168 "Content-Type: application/octet-stream"; | |
169 | 177 |
170 // MimeWriter manages an iovec for writing MIMEs to a file. | 178 // MimeWriter manages an iovec for writing MIMEs to a file. |
171 class MimeWriter { | 179 class MimeWriter { |
172 public: | 180 public: |
173 static const int kIovCapacity = 30; | 181 static const int kIovCapacity = 30; |
174 static const size_t kMaxCrashChunkSize = 64; | 182 static const size_t kMaxCrashChunkSize = 64; |
175 | 183 |
176 MimeWriter(int fd, const char* const mime_boundary); | 184 MimeWriter(int fd, const char* const mime_boundary); |
177 ~MimeWriter(); | 185 ~MimeWriter(); |
178 | 186 |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 size--; | 344 size--; |
337 } | 345 } |
338 AddItem(base, size); | 346 AddItem(base, size); |
339 } | 347 } |
340 | 348 |
341 void DumpProcess() { | 349 void DumpProcess() { |
342 if (g_breakpad) | 350 if (g_breakpad) |
343 g_breakpad->WriteMinidump(); | 351 g_breakpad->WriteMinidump(); |
344 } | 352 } |
345 | 353 |
| 354 const char kGoogleBreakpad[] = "google-breakpad"; |
| 355 |
346 size_t WriteLog(const char* buf, size_t nbytes) { | 356 size_t WriteLog(const char* buf, size_t nbytes) { |
347 #if defined(OS_ANDROID) | 357 #if defined(OS_ANDROID) |
348 return __android_log_write(ANDROID_LOG_WARN, "google-breakpad", buf); | 358 return __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, buf); |
349 #else | 359 #else |
350 return sys_write(2, buf, nbytes); | 360 return sys_write(2, buf, nbytes); |
351 #endif | 361 #endif |
352 } | 362 } |
353 | 363 |
354 } // namespace | 364 } // namespace |
355 | 365 |
356 void HandleCrashDump(const BreakpadInfo& info) { | 366 void HandleCrashDump(const BreakpadInfo& info) { |
357 // WARNING: this code runs in a compromised context. It may not call into | 367 // WARNING: this code runs in a compromised context. It may not call into |
358 // libc nor allocate memory normally. | 368 // libc nor allocate memory normally. |
359 | 369 |
360 const int dumpfd = sys_open(info.filename, O_RDONLY, 0); | 370 const int dumpfd = sys_open(info.filename, O_RDONLY, 0); |
361 if (dumpfd < 0) { | 371 if (dumpfd < 0) { |
362 static const char msg[] = "Cannot upload crash dump: failed to open\n"; | 372 static const char msg[] = "Cannot upload crash dump: failed to open\n"; |
363 WriteLog(msg, sizeof(msg)); | 373 WriteLog(msg, sizeof(msg)); |
364 return; | 374 return; |
365 } | 375 } |
366 #if defined(OS_ANDROID) | 376 STAT_STRUCT st; |
367 struct stat st; | 377 if (FSTAT_FUNC(dumpfd, &st) != 0) { |
368 if (fstat(dumpfd, &st) != 0) { | |
369 #else | |
370 struct kernel_stat st; | |
371 if (sys_fstat(dumpfd, &st) != 0) { | |
372 #endif | |
373 static const char msg[] = "Cannot upload crash dump: stat failed\n"; | 378 static const char msg[] = "Cannot upload crash dump: stat failed\n"; |
374 WriteLog(msg, sizeof(msg)); | 379 WriteLog(msg, sizeof(msg)); |
375 IGNORE_RET(sys_close(dumpfd)); | 380 IGNORE_RET(sys_close(dumpfd)); |
376 return; | 381 return; |
377 } | 382 } |
378 | 383 |
379 google_breakpad::PageAllocator allocator; | 384 google_breakpad::PageAllocator allocator; |
380 | 385 |
381 uint8_t* dump_data = reinterpret_cast<uint8_t*>(allocator.Alloc(st.st_size)); | 386 uint8_t* dump_data = reinterpret_cast<uint8_t*>(allocator.Alloc(st.st_size)); |
382 if (!dump_data) { | 387 if (!dump_data) { |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 static const char chrome_product_msg[] = "Chrome_ChromeOS"; | 538 static const char chrome_product_msg[] = "Chrome_ChromeOS"; |
534 #else // OS_LINUX | 539 #else // OS_LINUX |
535 static const char chrome_product_msg[] = "Chrome_Linux"; | 540 static const char chrome_product_msg[] = "Chrome_Linux"; |
536 #endif | 541 #endif |
537 | 542 |
538 #if defined (OS_ANDROID) | 543 #if defined (OS_ANDROID) |
539 base::android::BuildInfo* android_build_info = | 544 base::android::BuildInfo* android_build_info = |
540 base::android::BuildInfo::GetInstance(); | 545 base::android::BuildInfo::GetInstance(); |
541 static const char* version_msg = | 546 static const char* version_msg = |
542 android_build_info->package_version_code(); | 547 android_build_info->package_version_code(); |
543 static const char android_build_id[] = "android_build_id"; | |
544 static const char android_build_fp[] = "android_build_fp"; | |
545 static const char device[] = "device"; | |
546 static const char model[] = "model"; | |
547 static const char brand[] = "brand"; | |
548 #else | 548 #else |
549 static const char version_msg[] = PRODUCT_VERSION; | 549 static const char version_msg[] = PRODUCT_VERSION; |
550 #endif | 550 #endif |
551 | 551 |
552 writer.AddBoundary(); | 552 writer.AddBoundary(); |
553 writer.AddPairString("prod", chrome_product_msg); | 553 writer.AddPairString("prod", chrome_product_msg); |
554 writer.AddBoundary(); | 554 writer.AddBoundary(); |
555 writer.AddPairString("ver", version_msg); | 555 writer.AddPairString("ver", version_msg); |
556 writer.AddBoundary(); | 556 writer.AddBoundary(); |
557 writer.AddPairString("guid", info.guid); | 557 writer.AddPairString("guid", info.guid); |
558 writer.AddBoundary(); | 558 writer.AddBoundary(); |
559 if (info.pid > 0) { | 559 if (info.pid > 0) { |
| 560 char pid_buf[kUint64StringSize]; |
560 uint64_t pid_str_len = my_uint64_len(info.pid); | 561 uint64_t pid_str_len = my_uint64_len(info.pid); |
561 char* pid_buf = reinterpret_cast<char*>(allocator.Alloc(pid_str_len)); | |
562 my_uint64tos(pid_buf, info.pid, pid_str_len); | 562 my_uint64tos(pid_buf, info.pid, pid_str_len); |
563 writer.AddPairString("pid", pid_buf); | 563 writer.AddPairString("pid", pid_buf); |
564 writer.AddBoundary(); | 564 writer.AddBoundary(); |
565 } | 565 } |
566 #if defined(OS_ANDROID) | 566 #if defined(OS_ANDROID) |
567 // Addtional MIME blocks are added for logging on Android devices. | 567 // Addtional MIME blocks are added for logging on Android devices. |
| 568 static const char android_build_id[] = "android_build_id"; |
| 569 static const char android_build_fp[] = "android_build_fp"; |
| 570 static const char device[] = "device"; |
| 571 static const char model[] = "model"; |
| 572 static const char brand[] = "brand"; |
| 573 |
568 writer.AddPairString( | 574 writer.AddPairString( |
569 android_build_id, android_build_info->android_build_id()); | 575 android_build_id, android_build_info->android_build_id()); |
570 writer.AddBoundary(); | 576 writer.AddBoundary(); |
571 writer.AddPairString( | 577 writer.AddPairString( |
572 android_build_fp, android_build_info->android_build_fp()); | 578 android_build_fp, android_build_info->android_build_fp()); |
573 writer.AddBoundary(); | 579 writer.AddBoundary(); |
574 writer.AddPairString(device, android_build_info->device()); | 580 writer.AddPairString(device, android_build_info->device()); |
575 writer.AddBoundary(); | 581 writer.AddBoundary(); |
576 writer.AddPairString(model, android_build_info->model()); | 582 writer.AddPairString(model, android_build_info->model()); |
577 writer.AddBoundary(); | 583 writer.AddBoundary(); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 oom_size_str, oom_size_len); | 724 oom_size_str, oom_size_len); |
719 writer.AddBoundary(); | 725 writer.AddBoundary(); |
720 writer.Flush(); | 726 writer.Flush(); |
721 } | 727 } |
722 | 728 |
723 writer.AddFileDump(dump_data, st.st_size); | 729 writer.AddFileDump(dump_data, st.st_size); |
724 writer.AddEnd(); | 730 writer.AddEnd(); |
725 writer.Flush(); | 731 writer.Flush(); |
726 | 732 |
727 IGNORE_RET(sys_close(temp_file_fd)); | 733 IGNORE_RET(sys_close(temp_file_fd)); |
| 734 |
728 #if defined(OS_ANDROID) | 735 #if defined(OS_ANDROID) |
| 736 __android_log_write(ANDROID_LOG_WARN, |
| 737 kGoogleBreakpad, |
| 738 "Output crash dump file:"); |
| 739 __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, info.filename); |
| 740 |
| 741 char pid_buf[kUint64StringSize]; |
729 uint64_t pid_str_len = my_uint64_len(info.pid); | 742 uint64_t pid_str_len = my_uint64_len(info.pid); |
730 char* pid_buf = reinterpret_cast<char*>(allocator.Alloc(pid_str_len)); | |
731 my_uint64tos(pid_buf, info.pid, pid_str_len); | 743 my_uint64tos(pid_buf, info.pid, pid_str_len); |
732 | 744 |
733 static const char* output_msg = "Output crash dump file:"; | |
734 WriteLog(output_msg, my_strlen(output_msg)); | |
735 unsigned filename_len = my_strlen(info.filename); | |
736 WriteLog(info.filename, filename_len); | |
737 // -1 because we won't need the null terminator on the original filename. | 745 // -1 because we won't need the null terminator on the original filename. |
738 size_t done_filename_len = filename_len - 1 + pid_str_len; | 746 size_t done_filename_len = my_strlen(info.filename) + pid_str_len - 1; |
739 char* done_filename = reinterpret_cast<char*>( | 747 char* done_filename = reinterpret_cast<char*>( |
740 allocator.Alloc(done_filename_len)); | 748 allocator.Alloc(done_filename_len)); |
741 // Rename the file such that the pid is the suffix in order to signal other | 749 // Rename the file such that the pid is the suffix in order to signal other |
742 // processes that the minidump is complete. The advantage of using the pid as | 750 // processes that the minidump is complete. The advantage of using the pid as |
743 // the suffix is that it is trivial to associate the minidump with the | 751 // the suffix is that it is trivial to associate the minidump with the |
744 // crashed process. | 752 // crashed process. |
745 // Finally, note strncpy prevents null terminators from | 753 // Finally, note strncpy prevents null terminators from |
746 // being copied. Pad the rest with 0's. | 754 // being copied. Pad the rest with 0's. |
747 my_strncpy(done_filename, info.filename, done_filename_len); | 755 my_strncpy(done_filename, info.filename, done_filename_len); |
748 // Append the suffix a null terminator should be added. | 756 // Append the suffix a null terminator should be added. |
749 my_strncat(done_filename, pid_buf, pid_str_len); | 757 my_strncat(done_filename, pid_buf, pid_str_len); |
750 // Rename the minidump file to signal that it is complete. | 758 // Rename the minidump file to signal that it is complete. |
751 if (rename(info.filename, done_filename)) { | 759 if (rename(info.filename, done_filename)) { |
752 __android_log_write(ANDROID_LOG_WARN, "chromium", "Failed to rename:"); | 760 __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, "Failed to rename:"); |
753 __android_log_write(ANDROID_LOG_WARN, "chromium", info.filename); | 761 __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, info.filename); |
754 __android_log_write(ANDROID_LOG_WARN, "chromium", "to"); | 762 __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, "to"); |
755 __android_log_write(ANDROID_LOG_WARN, "chromium", done_filename); | 763 __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, done_filename); |
756 } | 764 } |
757 #endif | 765 #endif |
758 | 766 |
759 if (!info.upload) | 767 if (!info.upload) |
760 return; | 768 return; |
761 | 769 |
762 // The --header argument to wget looks like: | 770 // The --header argument to wget looks like: |
763 // --header=Content-Type: multipart/form-data; boundary=XYZ | 771 // --header=Content-Type: multipart/form-data; boundary=XYZ |
764 // where the boundary has two fewer leading '-' chars | 772 // where the boundary has two fewer leading '-' chars |
765 static const char header_msg[] = | 773 static const char header_msg[] = |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
813 | 821 |
814 // Leave one end of a pipe in the wget process and watch for it getting | 822 // Leave one end of a pipe in the wget process and watch for it getting |
815 // closed by the wget process exiting. | 823 // closed by the wget process exiting. |
816 int fds[2]; | 824 int fds[2]; |
817 if (sys_pipe(fds) >= 0) { | 825 if (sys_pipe(fds) >= 0) { |
818 const pid_t wget_child = sys_fork(); | 826 const pid_t wget_child = sys_fork(); |
819 if (!wget_child) { | 827 if (!wget_child) { |
820 // Wget process. | 828 // Wget process. |
821 IGNORE_RET(sys_close(fds[0])); | 829 IGNORE_RET(sys_close(fds[0])); |
822 IGNORE_RET(sys_dup2(fds[1], 3)); | 830 IGNORE_RET(sys_dup2(fds[1], 3)); |
823 static const char* const kWgetBinary = "/usr/bin/wget"; | 831 static const char kWgetBinary[] = "/usr/bin/wget"; |
824 const char* args[] = { | 832 const char* args[] = { |
825 kWgetBinary, | 833 kWgetBinary, |
826 header, | 834 header, |
827 post_file, | 835 post_file, |
828 kUploadURL, | 836 kUploadURL, |
829 "--timeout=10", // Set a timeout so we don't hang forever. | 837 "--timeout=10", // Set a timeout so we don't hang forever. |
830 "--tries=1", // Don't retry if the upload fails. | 838 "--tries=1", // Don't retry if the upload fails. |
831 "-O", // output reply to fd 3 | 839 "-O", // output reply to fd 3 |
832 "/dev/fd/3", | 840 "/dev/fd/3", |
833 NULL, | 841 NULL, |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
943 info.upload = upload; | 951 info.upload = upload; |
944 info.process_start_time = g_process_start_time; | 952 info.process_start_time = g_process_start_time; |
945 info.oom_size = base::g_oom_size; | 953 info.oom_size = base::g_oom_size; |
946 info.pid = 0; | 954 info.pid = 0; |
947 HandleCrashDump(info); | 955 HandleCrashDump(info); |
948 return true; | 956 return true; |
949 } | 957 } |
950 | 958 |
951 // Wrapper function, do not add more code here. | 959 // Wrapper function, do not add more code here. |
952 static bool CrashDoneNoUpload(const char* dump_path, | 960 static bool CrashDoneNoUpload(const char* dump_path, |
953 const char* minidump_id, | 961 const char* minidump_id, |
954 void* context, | 962 void* context, |
955 bool succeeded) { | 963 bool succeeded) { |
956 return CrashDone(dump_path, minidump_id, false, succeeded); | 964 return CrashDone(dump_path, minidump_id, false, succeeded); |
957 } | 965 } |
958 | 966 |
959 #if !defined(OS_ANDROID) | 967 #if !defined(OS_ANDROID) |
960 // Wrapper function, do not add more code here. | 968 // Wrapper function, do not add more code here. |
961 static bool CrashDoneUpload(const char* dump_path, | 969 static bool CrashDoneUpload(const char* dump_path, |
962 const char* minidump_id, | 970 const char* minidump_id, |
963 void* context, | 971 void* context, |
964 bool succeeded) { | 972 bool succeeded) { |
965 return CrashDone(dump_path, minidump_id, true, succeeded); | 973 return CrashDone(dump_path, minidump_id, true, succeeded); |
966 } | 974 } |
967 #endif | 975 #endif |
968 | 976 |
969 void EnableCrashDumping(bool unattended) { | 977 static void EnableCrashDumping(bool unattended) { |
970 g_is_crash_reporter_enabled = true; | 978 g_is_crash_reporter_enabled = true; |
971 | 979 |
972 FilePath tmp_path("/tmp"); | 980 FilePath tmp_path("/tmp"); |
973 PathService::Get(base::DIR_TEMP, &tmp_path); | 981 PathService::Get(base::DIR_TEMP, &tmp_path); |
974 | 982 |
975 FilePath dumps_path(tmp_path); | 983 FilePath dumps_path(tmp_path); |
976 if (PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path)) { | 984 if (PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path)) { |
977 FilePath logfile = | 985 FilePath logfile = |
978 dumps_path.AppendASCII(CrashUploadList::kReporterLogFilename); | 986 dumps_path.AppendASCII(CrashUploadList::kReporterLogFilename); |
979 std::string logfile_str = logfile.value(); | 987 std::string logfile_str = logfile.value(); |
980 const size_t crash_log_path_len = logfile_str.size() + 1; | 988 const size_t crash_log_path_len = logfile_str.size() + 1; |
981 g_crash_log_path = new char[crash_log_path_len]; | 989 g_crash_log_path = new char[crash_log_path_len]; |
982 strncpy(g_crash_log_path, logfile_str.c_str(), crash_log_path_len); | 990 strncpy(g_crash_log_path, logfile_str.c_str(), crash_log_path_len); |
983 } | 991 } |
984 DCHECK(!g_breakpad); | 992 DCHECK(!g_breakpad); |
985 #if defined(OS_ANDROID) | 993 #if defined(OS_ANDROID) |
986 unattended = true; | 994 unattended = true; // Android never uploads directly. |
987 #endif | 995 #endif |
988 if (unattended) { | 996 if (unattended) { |
989 g_breakpad = new google_breakpad::ExceptionHandler( | 997 g_breakpad = new google_breakpad::ExceptionHandler( |
990 dumps_path.value().c_str(), | 998 dumps_path.value().c_str(), |
991 NULL, | 999 NULL, |
992 CrashDoneNoUpload, | 1000 CrashDoneNoUpload, |
993 NULL, | 1001 NULL, |
994 true /* install handlers */); | 1002 true /* install handlers */); |
995 } else { | 1003 return; |
996 g_breakpad = new google_breakpad::ExceptionHandler( | |
997 tmp_path.value().c_str(), | |
998 NULL, | |
999 CrashDoneUpload, | |
1000 NULL, | |
1001 true /* install handlers */); | |
1002 } | 1004 } |
| 1005 |
| 1006 #if !defined(OS_ANDROID) |
| 1007 // Attended mode |
| 1008 g_breakpad = new google_breakpad::ExceptionHandler( |
| 1009 tmp_path.value().c_str(), |
| 1010 NULL, |
| 1011 CrashDoneUpload, |
| 1012 NULL, |
| 1013 true /* install handlers */); |
| 1014 #endif |
1003 } | 1015 } |
1004 | 1016 |
1005 // Non-Browser = Extension, Gpu, Plugins, Ppapi and Renderer | 1017 // Non-Browser = Extension, Gpu, Plugins, Ppapi and Renderer |
1006 static bool NonBrowserCrashHandler(const void* crash_context, | 1018 static bool NonBrowserCrashHandler(const void* crash_context, |
1007 size_t crash_context_size, | 1019 size_t crash_context_size, |
1008 void* context) { | 1020 void* context) { |
1009 const int fd = reinterpret_cast<intptr_t>(context); | 1021 const int fd = reinterpret_cast<intptr_t>(context); |
1010 int fds[2] = { -1, -1 }; | 1022 int fds[2] = { -1, -1 }; |
1011 if (sys_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) { | 1023 if (sys_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) { |
1012 static const char msg[] = "Failed to create socket for crash dumping.\n"; | 1024 static const char msg[] = "Failed to create socket for crash dumping.\n"; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1094 IGNORE_RET(sys_close(fds[1])); | 1106 IGNORE_RET(sys_close(fds[1])); |
1095 | 1107 |
1096 if (HANDLE_EINTR(sys_read(fds[0], &b, 1)) != 1) { | 1108 if (HANDLE_EINTR(sys_read(fds[0], &b, 1)) != 1) { |
1097 static const char errmsg[] = "Parent failed to complete crash dump.\n"; | 1109 static const char errmsg[] = "Parent failed to complete crash dump.\n"; |
1098 WriteLog(errmsg, sizeof(errmsg)-1); | 1110 WriteLog(errmsg, sizeof(errmsg)-1); |
1099 } | 1111 } |
1100 | 1112 |
1101 return true; | 1113 return true; |
1102 } | 1114 } |
1103 | 1115 |
1104 void EnableNonBrowserCrashDumping() { | 1116 static void EnableNonBrowserCrashDumping() { |
1105 const int fd = base::GlobalDescriptors::GetInstance()->Get(kCrashDumpSignal); | 1117 const int fd = base::GlobalDescriptors::GetInstance()->Get(kCrashDumpSignal); |
1106 g_is_crash_reporter_enabled = true; | 1118 g_is_crash_reporter_enabled = true; |
1107 // We deliberately leak this object. | 1119 // We deliberately leak this object. |
1108 DCHECK(!g_breakpad); | 1120 DCHECK(!g_breakpad); |
1109 g_breakpad = new google_breakpad::ExceptionHandler( | 1121 g_breakpad = new google_breakpad::ExceptionHandler( |
1110 "" /* unused */, NULL, NULL, reinterpret_cast<void*>(fd), true); | 1122 "" /* unused */, NULL, NULL, reinterpret_cast<void*>(fd), true); |
1111 g_breakpad->set_crash_handler(NonBrowserCrashHandler); | 1123 g_breakpad->set_crash_handler(NonBrowserCrashHandler); |
1112 } | 1124 } |
1113 | 1125 |
1114 void InitCrashReporter() { | 1126 void InitCrashReporter() { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1160 g_process_start_time = timeval_to_ms(&tv); | 1172 g_process_start_time = timeval_to_ms(&tv); |
1161 else | 1173 else |
1162 g_process_start_time = 0; | 1174 g_process_start_time = 0; |
1163 | 1175 |
1164 logging::SetDumpWithoutCrashingFunction(&DumpProcess); | 1176 logging::SetDumpWithoutCrashingFunction(&DumpProcess); |
1165 } | 1177 } |
1166 | 1178 |
1167 bool IsCrashReporterEnabled() { | 1179 bool IsCrashReporterEnabled() { |
1168 return g_is_crash_reporter_enabled; | 1180 return g_is_crash_reporter_enabled; |
1169 } | 1181 } |
OLD | NEW |