| 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 |