Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 | 7 |
| 8 #include "components/crash/app/breakpad_linux.h" | 8 #include "components/crash/app/breakpad_linux.h" |
| 9 | 9 |
| 10 #include <fcntl.h> | 10 #include <fcntl.h> |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 #include "components/crash/app/breakpad_linux_impl.h" | 42 #include "components/crash/app/breakpad_linux_impl.h" |
| 43 #include "components/crash/app/crash_reporter_client.h" | 43 #include "components/crash/app/crash_reporter_client.h" |
| 44 #include "content/public/common/content_descriptors.h" | 44 #include "content/public/common/content_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 | 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 "base/lazy_instance.h" | |
| 52 #endif | 53 #endif |
| 53 #include "third_party/lss/linux_syscall_support.h" | 54 #include "third_party/lss/linux_syscall_support.h" |
| 54 | 55 |
| 55 #if defined(ADDRESS_SANITIZER) | 56 #if defined(ADDRESS_SANITIZER) |
| 56 #include <ucontext.h> // for getcontext(). | 57 #include <ucontext.h> // for getcontext(). |
| 57 #endif | 58 #endif |
| 58 | 59 |
| 59 #if defined(OS_ANDROID) | 60 #if defined(OS_ANDROID) |
| 60 #define STAT_STRUCT struct stat | 61 #define STAT_STRUCT struct stat |
| 61 #define FSTAT_FUNC fstat | 62 #define FSTAT_FUNC fstat |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 78 | 79 |
| 79 namespace { | 80 namespace { |
| 80 | 81 |
| 81 #if !defined(OS_CHROMEOS) | 82 #if !defined(OS_CHROMEOS) |
| 82 const char kUploadURL[] = "https://clients2.google.com/cr/report"; | 83 const char kUploadURL[] = "https://clients2.google.com/cr/report"; |
| 83 #endif | 84 #endif |
| 84 | 85 |
| 85 bool g_is_crash_reporter_enabled = false; | 86 bool g_is_crash_reporter_enabled = false; |
| 86 uint64_t g_process_start_time = 0; | 87 uint64_t g_process_start_time = 0; |
| 87 pid_t g_pid = 0; | 88 pid_t g_pid = 0; |
| 88 char* g_crash_log_path = NULL; | 89 char* g_crash_log_path = nullptr; |
| 89 ExceptionHandler* g_breakpad = NULL; | 90 ExceptionHandler* g_breakpad = nullptr; |
| 90 ExceptionHandler* g_microdump = NULL; | 91 |
| 92 #if defined(OS_ANDROID) | |
| 93 ExceptionHandler* g_microdump = nullptr; | |
| 94 | |
| 95 base::LazyInstance<std::string>::Leaky g_microdump_build_fingerprint = | |
| 96 LAZY_INSTANCE_INITIALIZER; | |
| 97 const char* g_c_microdump_build_fingerprint = nullptr; | |
| 98 | |
| 99 base::LazyInstance<std::string>::Leaky g_microdump_product_info = | |
| 100 LAZY_INSTANCE_INITIALIZER; | |
| 101 const char* g_c_microdump_product_info = nullptr; | |
| 102 #endif | |
| 91 | 103 |
| 92 #if defined(ADDRESS_SANITIZER) | 104 #if defined(ADDRESS_SANITIZER) |
| 93 const char* g_asan_report_str = NULL; | 105 const char* g_asan_report_str = nullptr; |
| 94 #endif | 106 #endif |
| 95 #if defined(OS_ANDROID) | 107 #if defined(OS_ANDROID) |
| 96 char* g_process_type = NULL; | 108 char* g_process_type = nullptr; |
| 97 #endif | 109 #endif |
| 98 | 110 |
| 99 CrashKeyStorage* g_crash_keys = NULL; | 111 CrashKeyStorage* g_crash_keys = nullptr; |
| 100 | 112 |
| 101 // Writes the value |v| as 16 hex characters to the memory pointed at by | 113 // Writes the value |v| as 16 hex characters to the memory pointed at by |
| 102 // |output|. | 114 // |output|. |
| 103 void write_uint64_hex(char* output, uint64_t v) { | 115 void write_uint64_hex(char* output, uint64_t v) { |
| 104 static const char hextable[] = "0123456789abcdef"; | 116 static const char hextable[] = "0123456789abcdef"; |
| 105 | 117 |
| 106 for (int i = 15; i >= 0; --i) { | 118 for (int i = 15; i >= 0; --i) { |
| 107 output[i] = hextable[v & 15]; | 119 output[i] = hextable[v & 15]; |
| 108 v >>= 4; | 120 v >>= 4; |
| 109 } | 121 } |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 126 ret += tv->tv_usec / 1000; | 138 ret += tv->tv_usec / 1000; |
| 127 return ret; | 139 return ret; |
| 128 } | 140 } |
| 129 | 141 |
| 130 // String buffer size to use to convert a uint64_t to string. | 142 // String buffer size to use to convert a uint64_t to string. |
| 131 const size_t kUint64StringSize = 21; | 143 const size_t kUint64StringSize = 21; |
| 132 | 144 |
| 133 void SetProcessStartTime() { | 145 void SetProcessStartTime() { |
| 134 // Set the base process start time value. | 146 // Set the base process start time value. |
| 135 struct timeval tv; | 147 struct timeval tv; |
| 136 if (!gettimeofday(&tv, NULL)) | 148 if (!gettimeofday(&tv, nullptr)) |
| 137 g_process_start_time = timeval_to_ms(&tv); | 149 g_process_start_time = timeval_to_ms(&tv); |
| 138 else | 150 else |
| 139 g_process_start_time = 0; | 151 g_process_start_time = 0; |
| 140 } | 152 } |
| 141 | 153 |
| 142 // uint64_t version of my_int_len() from | 154 // uint64_t version of my_int_len() from |
| 143 // breakpad/src/common/linux/linux_libc_support.h. Return the length of the | 155 // breakpad/src/common/linux/linux_libc_support.h. Return the length of the |
| 144 // given, non-negative integer when expressed in base 10. | 156 // given, non-negative integer when expressed in base 10. |
| 145 unsigned my_uint64_len(uint64_t i) { | 157 unsigned my_uint64_len(uint64_t i) { |
| 146 if (!i) | 158 if (!i) |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 505 AddString(g_sep); | 517 AddString(g_sep); |
| 506 AddItem(file_data, file_size); | 518 AddItem(file_data, file_size); |
| 507 Flush(); | 519 Flush(); |
| 508 } | 520 } |
| 509 #endif // defined(OS_CHROMEOS) | 521 #endif // defined(OS_CHROMEOS) |
| 510 | 522 |
| 511 void DumpProcess() { | 523 void DumpProcess() { |
| 512 if (g_breakpad) | 524 if (g_breakpad) |
| 513 g_breakpad->WriteMinidump(); | 525 g_breakpad->WriteMinidump(); |
| 514 | 526 |
| 527 #if defined(OS_ANDROID) | |
| 515 // If microdumps are enabled write also a microdump on the system log. | 528 // If microdumps are enabled write also a microdump on the system log. |
| 516 if (g_microdump) | 529 if (g_microdump) |
| 517 g_microdump->WriteMinidump(); | 530 g_microdump->WriteMinidump(); |
| 531 #endif | |
| 518 } | 532 } |
| 519 | 533 |
| 520 #if defined(OS_ANDROID) | 534 #if defined(OS_ANDROID) |
| 521 const char kGoogleBreakpad[] = "google-breakpad"; | 535 const char kGoogleBreakpad[] = "google-breakpad"; |
| 522 #endif | 536 #endif |
| 523 | 537 |
| 524 size_t WriteLog(const char* buf, size_t nbytes) { | 538 size_t WriteLog(const char* buf, size_t nbytes) { |
| 525 #if defined(OS_ANDROID) | 539 #if defined(OS_ANDROID) |
| 526 return __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, buf); | 540 return __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, buf); |
| 527 #else | 541 #else |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 671 minidump_descriptor.set_size_limit(-1); // unlimited. | 685 minidump_descriptor.set_size_limit(-1); // unlimited. |
| 672 } else { | 686 } else { |
| 673 minidump_descriptor.set_size_limit(kMaxMinidumpFileSize); | 687 minidump_descriptor.set_size_limit(kMaxMinidumpFileSize); |
| 674 } | 688 } |
| 675 #if defined(OS_ANDROID) | 689 #if defined(OS_ANDROID) |
| 676 unattended = true; // Android never uploads directly. | 690 unattended = true; // Android never uploads directly. |
| 677 #endif | 691 #endif |
| 678 if (unattended) { | 692 if (unattended) { |
| 679 g_breakpad = new ExceptionHandler( | 693 g_breakpad = new ExceptionHandler( |
| 680 minidump_descriptor, | 694 minidump_descriptor, |
| 681 NULL, | 695 nullptr, |
| 682 CrashDoneNoUpload, | 696 CrashDoneNoUpload, |
| 683 NULL, | 697 nullptr, |
| 684 true, // Install handlers. | 698 true, // Install handlers. |
| 685 -1); // Server file descriptor. -1 for in-process. | 699 -1); // Server file descriptor. -1 for in-process. |
| 686 return; | 700 return; |
| 687 } | 701 } |
| 688 | 702 |
| 689 #if !defined(OS_ANDROID) | 703 #if !defined(OS_ANDROID) |
| 690 // Attended mode | 704 // Attended mode |
| 691 g_breakpad = new ExceptionHandler( | 705 g_breakpad = new ExceptionHandler( |
| 692 minidump_descriptor, | 706 minidump_descriptor, |
| 693 NULL, | 707 nullptr, |
| 694 CrashDoneUpload, | 708 CrashDoneUpload, |
| 695 NULL, | 709 nullptr, |
| 696 true, // Install handlers. | 710 true, // Install handlers. |
| 697 -1); // Server file descriptor. -1 for in-process. | 711 -1); // Server file descriptor. -1 for in-process. |
| 698 #endif | 712 #endif |
| 699 } | 713 } |
| 700 | 714 |
| 701 #if defined(OS_ANDROID) | 715 #if defined(OS_ANDROID) |
| 702 bool MicrodumpCrashDone(const MinidumpDescriptor& minidump, | 716 bool MicrodumpCrashDone(const MinidumpDescriptor& minidump, |
| 703 void* context, | 717 void* context, |
| 704 bool succeeded) { | 718 bool succeeded) { |
| 705 // WARNING: this code runs in a compromised context. It may not call into | 719 // WARNING: this code runs in a compromised context. It may not call into |
| 706 // libc nor allocate memory normally. | 720 // libc nor allocate memory normally. |
| 707 if (!succeeded) { | 721 if (!succeeded) { |
| 708 static const char msg[] = "Microdump crash handler failed.\n"; | 722 static const char msg[] = "Microdump crash handler failed.\n"; |
| 709 WriteLog(msg, sizeof(msg) - 1); | 723 WriteLog(msg, sizeof(msg) - 1); |
| 710 return false; | 724 return false; |
| 711 } | 725 } |
| 712 | 726 |
| 713 const bool is_browser_process = (context != NULL); | 727 const bool is_browser_process = (context != nullptr); |
| 714 return FinalizeCrashDoneAndroid(is_browser_process); | 728 return FinalizeCrashDoneAndroid(is_browser_process); |
| 715 } | 729 } |
| 716 | 730 |
| 717 // The microdump handler does NOT upload anything. It just dumps out on the | 731 // The microdump handler does NOT upload anything. It just dumps out on the |
| 718 // system console (logcat) a restricted and serialized variant of a minidump. | 732 // system console (logcat) a restricted and serialized variant of a minidump. |
| 719 // See crbug.com/410294 for more details. | 733 // See crbug.com/410294 for more details. |
| 720 void InitMicrodumpCrashHandlerIfNecessary(const std::string& process_type) { | 734 void InitMicrodumpCrashHandlerIfNecessary(const std::string& process_type) { |
| 721 #if (!defined(ARCH_CPU_ARMEL) && !defined(ARCH_CPU_ARM64)) | 735 #if (!defined(ARCH_CPU_ARMEL) && !defined(ARCH_CPU_ARM64)) |
| 722 // TODO(primiano): For the moment microdumps are enabled only on arm (32/64). | 736 // TODO(primiano): For the moment microdumps are enabled only on arm (32/64). |
| 723 // Extend support to other architectures (requires some breakpad changes). | 737 // Extend support to other architectures (requires some breakpad changes). |
| 724 return; | 738 return; |
| 725 #endif | 739 #endif |
| 726 | 740 |
| 727 if (!GetCrashReporterClient()->ShouldEnableBreakpadMicrodumps()) | 741 if (!GetCrashReporterClient()->ShouldEnableBreakpadMicrodumps()) |
| 728 return; | 742 return; |
| 729 | 743 |
| 730 VLOG(1) << "Enabling microdumps crash handler (process_type:" | 744 VLOG(1) << "Enabling microdumps crash handler (process_type:" |
| 731 << process_type << ")"; | 745 << process_type << ")"; |
| 746 | |
| 747 const char* product_name = nullptr; | |
| 748 const char* product_version = nullptr; | |
| 749 GetCrashReporterClient()->GetProductNameAndVersion(&product_name, | |
| 750 &product_version); | |
| 751 g_microdump_product_info.Get() = product_name + string(":") + product_version; | |
| 752 g_microdump_build_fingerprint.Get() = | |
|
Lei Zhang
2015/05/15 10:37:18
or maybe get rid of the LazyInstance, and just do:
Primiano Tucci (use gerrit)
2015/05/15 11:41:44
Yeah, I guess it's easier to read if I leak string
| |
| 753 base::android::BuildInfo::GetInstance()->android_build_fp(); | |
| 754 | |
| 755 // The exception handler runs in a compromised context and cannot use c_str() | |
| 756 // as that would require the heap. Therefore, we have to guarantee that the | |
| 757 // build fingerprint and product info pointers are always valid. | |
| 758 g_c_microdump_product_info = g_microdump_product_info.Get().c_str(); | |
| 759 g_c_microdump_build_fingerprint = g_microdump_build_fingerprint.Get().c_str(); | |
| 760 | |
| 761 MinidumpDescriptor descriptor(MinidumpDescriptor::kMicrodumpOnConsole); | |
| 762 descriptor.SetMicrodumpProductInfo(g_c_microdump_product_info); | |
| 763 descriptor.SetMicrodumpBuildFingerprint(g_c_microdump_build_fingerprint); | |
| 764 | |
| 732 DCHECK(!g_microdump); | 765 DCHECK(!g_microdump); |
| 733 bool is_browser_process = process_type.empty() || process_type == "webview"; | 766 bool is_browser_process = process_type.empty() || process_type == "webview"; |
| 734 g_microdump = new ExceptionHandler( | 767 g_microdump = new ExceptionHandler( |
| 735 MinidumpDescriptor(MinidumpDescriptor::kMicrodumpOnConsole), | 768 descriptor, |
| 736 NULL, | 769 nullptr, |
| 737 MicrodumpCrashDone, | 770 MicrodumpCrashDone, |
| 738 reinterpret_cast<void*>(is_browser_process), | 771 reinterpret_cast<void*>(is_browser_process), |
| 739 true, // Install handlers. | 772 true, // Install handlers. |
| 740 -1); // Server file descriptor. -1 for in-process. | 773 -1); // Server file descriptor. -1 for in-process. |
| 741 return; | 774 return; |
| 742 } | 775 } |
| 743 | 776 |
| 744 bool CrashDoneInProcessNoUpload( | 777 bool CrashDoneInProcessNoUpload( |
| 745 const google_breakpad::MinidumpDescriptor& descriptor, | 778 const google_breakpad::MinidumpDescriptor& descriptor, |
| 746 void* context, | 779 void* context, |
| 747 const bool succeeded) { | 780 const bool succeeded) { |
| 748 // WARNING: this code runs in a compromised context. It may not call into | 781 // WARNING: this code runs in a compromised context. It may not call into |
| 749 // libc nor allocate memory normally. | 782 // libc nor allocate memory normally. |
| 750 if (!succeeded) { | 783 if (!succeeded) { |
| 751 static const char msg[] = "Crash dump generation failed.\n"; | 784 static const char msg[] = "Crash dump generation failed.\n"; |
| 752 WriteLog(msg, sizeof(msg) - 1); | 785 WriteLog(msg, sizeof(msg) - 1); |
| 753 return false; | 786 return false; |
| 754 } | 787 } |
| 755 | 788 |
| 756 // Start constructing the message to send to the browser. | 789 // Start constructing the message to send to the browser. |
| 757 BreakpadInfo info = {0}; | 790 BreakpadInfo info = {0}; |
| 758 info.filename = NULL; | 791 info.filename = nullptr; |
| 759 info.fd = descriptor.fd(); | 792 info.fd = descriptor.fd(); |
| 760 info.process_type = g_process_type; | 793 info.process_type = g_process_type; |
| 761 info.process_type_length = my_strlen(g_process_type); | 794 info.process_type_length = my_strlen(g_process_type); |
| 762 info.distro = NULL; | 795 info.distro = nullptr; |
| 763 info.distro_length = 0; | 796 info.distro_length = 0; |
| 764 info.upload = false; | 797 info.upload = false; |
| 765 info.process_start_time = g_process_start_time; | 798 info.process_start_time = g_process_start_time; |
| 766 info.pid = g_pid; | 799 info.pid = g_pid; |
| 767 info.crash_keys = g_crash_keys; | 800 info.crash_keys = g_crash_keys; |
| 768 HandleCrashDump(info); | 801 HandleCrashDump(info); |
| 769 return FinalizeCrashDoneAndroid(false /* is_browser_process */); | 802 return FinalizeCrashDoneAndroid(false /* is_browser_process */); |
| 770 } | 803 } |
| 771 | 804 |
| 772 void EnableNonBrowserCrashDumping(const std::string& process_type, | 805 void EnableNonBrowserCrashDumping(const std::string& process_type, |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 791 } | 824 } |
| 792 SetProcessStartTime(); | 825 SetProcessStartTime(); |
| 793 g_pid = getpid(); | 826 g_pid = getpid(); |
| 794 | 827 |
| 795 g_is_crash_reporter_enabled = true; | 828 g_is_crash_reporter_enabled = true; |
| 796 // Save the process type (it is leaked). | 829 // Save the process type (it is leaked). |
| 797 const size_t process_type_len = process_type.size() + 1; | 830 const size_t process_type_len = process_type.size() + 1; |
| 798 g_process_type = new char[process_type_len]; | 831 g_process_type = new char[process_type_len]; |
| 799 strncpy(g_process_type, process_type.c_str(), process_type_len); | 832 strncpy(g_process_type, process_type.c_str(), process_type_len); |
| 800 new google_breakpad::ExceptionHandler(MinidumpDescriptor(minidump_fd), | 833 new google_breakpad::ExceptionHandler(MinidumpDescriptor(minidump_fd), |
| 801 NULL, CrashDoneInProcessNoUpload, NULL, true, -1); | 834 nullptr, CrashDoneInProcessNoUpload, nullptr, true, -1); |
| 802 } | 835 } |
| 803 #else | 836 #else |
| 804 // Non-Browser = Extension, Gpu, Plugins, Ppapi and Renderer | 837 // Non-Browser = Extension, Gpu, Plugins, Ppapi and Renderer |
| 805 class NonBrowserCrashHandler : public google_breakpad::CrashGenerationClient { | 838 class NonBrowserCrashHandler : public google_breakpad::CrashGenerationClient { |
| 806 public: | 839 public: |
| 807 NonBrowserCrashHandler() | 840 NonBrowserCrashHandler() |
| 808 : server_fd_(base::GlobalDescriptors::GetInstance()->Get( | 841 : server_fd_(base::GlobalDescriptors::GetInstance()->Get( |
| 809 kCrashDumpSignal)) { | 842 kCrashDumpSignal)) { |
| 810 } | 843 } |
| 811 | 844 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 895 DISALLOW_COPY_AND_ASSIGN(NonBrowserCrashHandler); | 928 DISALLOW_COPY_AND_ASSIGN(NonBrowserCrashHandler); |
| 896 }; | 929 }; |
| 897 | 930 |
| 898 void EnableNonBrowserCrashDumping() { | 931 void EnableNonBrowserCrashDumping() { |
| 899 g_is_crash_reporter_enabled = true; | 932 g_is_crash_reporter_enabled = true; |
| 900 // We deliberately leak this object. | 933 // We deliberately leak this object. |
| 901 DCHECK(!g_breakpad); | 934 DCHECK(!g_breakpad); |
| 902 | 935 |
| 903 g_breakpad = new ExceptionHandler( | 936 g_breakpad = new ExceptionHandler( |
| 904 MinidumpDescriptor("/tmp"), // Unused but needed or Breakpad will assert. | 937 MinidumpDescriptor("/tmp"), // Unused but needed or Breakpad will assert. |
| 905 NULL, | 938 nullptr, |
| 906 NULL, | 939 nullptr, |
| 907 NULL, | 940 nullptr, |
| 908 true, | 941 true, |
| 909 -1); | 942 -1); |
| 910 g_breakpad->set_crash_generation_client(new NonBrowserCrashHandler()); | 943 g_breakpad->set_crash_generation_client(new NonBrowserCrashHandler()); |
| 911 } | 944 } |
| 912 #endif // defined(OS_ANDROID) | 945 #endif // defined(OS_ANDROID) |
| 913 | 946 |
| 914 void SetCrashKeyValue(const base::StringPiece& key, | 947 void SetCrashKeyValue(const base::StringPiece& key, |
| 915 const base::StringPiece& value) { | 948 const base::StringPiece& value) { |
| 916 g_crash_keys->SetKeyValue(key.data(), value.data()); | 949 g_crash_keys->SetKeyValue(key.data(), value.data()); |
| 917 } | 950 } |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1050 exe_flag[0] = '\0'; | 1083 exe_flag[0] = '\0'; |
| 1051 my_strlcat(exe_flag, kExeBuf, buf_len); | 1084 my_strlcat(exe_flag, kExeBuf, buf_len); |
| 1052 my_strlcat(exe_flag, exe_buf, buf_len); | 1085 my_strlcat(exe_flag, exe_buf, buf_len); |
| 1053 | 1086 |
| 1054 const char* args[] = { | 1087 const char* args[] = { |
| 1055 kCrashReporterBinary, | 1088 kCrashReporterBinary, |
| 1056 chrome_flag, | 1089 chrome_flag, |
| 1057 pid_flag, | 1090 pid_flag, |
| 1058 uid_flag, | 1091 uid_flag, |
| 1059 exe_flag, | 1092 exe_flag, |
| 1060 NULL, | 1093 nullptr, |
| 1061 }; | 1094 }; |
| 1062 static const char msg[] = "Cannot upload crash dump: cannot exec " | 1095 static const char msg[] = "Cannot upload crash dump: cannot exec " |
| 1063 "/sbin/crash_reporter\n"; | 1096 "/sbin/crash_reporter\n"; |
| 1064 #else | 1097 #else |
| 1065 // The --header argument to wget looks like: | 1098 // The --header argument to wget looks like: |
| 1066 // --header=Content-Type: multipart/form-data; boundary=XYZ | 1099 // --header=Content-Type: multipart/form-data; boundary=XYZ |
| 1067 // where the boundary has two fewer leading '-' chars | 1100 // where the boundary has two fewer leading '-' chars |
| 1068 static const char header_msg[] = | 1101 static const char header_msg[] = |
| 1069 "--header=Content-Type: multipart/form-data; boundary="; | 1102 "--header=Content-Type: multipart/form-data; boundary="; |
| 1070 char* const header = reinterpret_cast<char*>(allocator->Alloc( | 1103 char* const header = reinterpret_cast<char*>(allocator->Alloc( |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1085 static const char kWgetBinary[] = "/usr/bin/wget"; | 1118 static const char kWgetBinary[] = "/usr/bin/wget"; |
| 1086 const char* args[] = { | 1119 const char* args[] = { |
| 1087 kWgetBinary, | 1120 kWgetBinary, |
| 1088 header, | 1121 header, |
| 1089 post_file, | 1122 post_file, |
| 1090 kUploadURL, | 1123 kUploadURL, |
| 1091 "--timeout=10", // Set a timeout so we don't hang forever. | 1124 "--timeout=10", // Set a timeout so we don't hang forever. |
| 1092 "--tries=1", // Don't retry if the upload fails. | 1125 "--tries=1", // Don't retry if the upload fails. |
| 1093 "-O", // output reply to fd 3 | 1126 "-O", // output reply to fd 3 |
| 1094 "/dev/fd/3", | 1127 "/dev/fd/3", |
| 1095 NULL, | 1128 nullptr, |
| 1096 }; | 1129 }; |
| 1097 static const char msg[] = "Cannot upload crash dump: cannot exec " | 1130 static const char msg[] = "Cannot upload crash dump: cannot exec " |
| 1098 "/usr/bin/wget\n"; | 1131 "/usr/bin/wget\n"; |
| 1099 #endif | 1132 #endif |
| 1100 execve(args[0], const_cast<char**>(args), environ); | 1133 execve(args[0], const_cast<char**>(args), environ); |
| 1101 WriteLog(msg, sizeof(msg) - 1); | 1134 WriteLog(msg, sizeof(msg) - 1); |
| 1102 sys__exit(1); | 1135 sys__exit(1); |
| 1103 } | 1136 } |
| 1104 | 1137 |
| 1105 // Runs in the helper process to wait for the upload process running | 1138 // Runs in the helper process to wait for the upload process running |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1130 if (bytes_read == bytes_to_read) | 1163 if (bytes_read == bytes_to_read) |
| 1131 break; | 1164 break; |
| 1132 } | 1165 } |
| 1133 // |ret| == 0 -> timed out, continue waiting. | 1166 // |ret| == 0 -> timed out, continue waiting. |
| 1134 // or |bytes_read| < |bytes_to_read| still, keep reading. | 1167 // or |bytes_read| < |bytes_to_read| still, keep reading. |
| 1135 } | 1168 } |
| 1136 buf[bytes_to_read] = 0; // Always NUL terminate the buffer. | 1169 buf[bytes_to_read] = 0; // Always NUL terminate the buffer. |
| 1137 return bytes_read; | 1170 return bytes_read; |
| 1138 } | 1171 } |
| 1139 | 1172 |
| 1140 // |buf| should be |expected_len| + 1 characters in size and NULL terminated. | 1173 // |buf| should be |expected_len| + 1 characters in size and nullptr terminated. |
| 1141 bool IsValidCrashReportId(const char* buf, size_t bytes_read, | 1174 bool IsValidCrashReportId(const char* buf, size_t bytes_read, |
| 1142 size_t expected_len) { | 1175 size_t expected_len) { |
| 1143 if (bytes_read != expected_len) | 1176 if (bytes_read != expected_len) |
| 1144 return false; | 1177 return false; |
| 1145 #if defined(OS_CHROMEOS) | 1178 #if defined(OS_CHROMEOS) |
| 1146 return my_strcmp(buf, "_sys_cr_finished") == 0; | 1179 return my_strcmp(buf, "_sys_cr_finished") == 0; |
| 1147 #else | 1180 #else |
| 1148 for (size_t i = 0; i < bytes_read; ++i) { | 1181 for (size_t i = 0; i < bytes_read; ++i) { |
| 1149 if (!my_isxdigit(buf[i])) | 1182 if (!my_isxdigit(buf[i])) |
| 1150 return false; | 1183 return false; |
| 1151 } | 1184 } |
| 1152 return true; | 1185 return true; |
| 1153 #endif | 1186 #endif |
| 1154 } | 1187 } |
| 1155 | 1188 |
| 1156 // |buf| should be |expected_len| + 1 characters in size and NULL terminated. | 1189 // |buf| should be |expected_len| + 1 characters in size and nullptr terminated. |
| 1157 void HandleCrashReportId(const char* buf, size_t bytes_read, | 1190 void HandleCrashReportId(const char* buf, size_t bytes_read, |
| 1158 size_t expected_len) { | 1191 size_t expected_len) { |
| 1159 WriteNewline(); | 1192 WriteNewline(); |
| 1160 if (!IsValidCrashReportId(buf, bytes_read, expected_len)) { | 1193 if (!IsValidCrashReportId(buf, bytes_read, expected_len)) { |
| 1161 #if defined(OS_CHROMEOS) | 1194 #if defined(OS_CHROMEOS) |
| 1162 static const char msg[] = | 1195 static const char msg[] = |
| 1163 "System crash-reporter failed to process crash report."; | 1196 "System crash-reporter failed to process crash report."; |
| 1164 #else | 1197 #else |
| 1165 static const char msg[] = "Failed to get crash dump id."; | 1198 static const char msg[] = "Failed to get crash dump id."; |
| 1166 #endif | 1199 #endif |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1179 WriteLog(msg, sizeof(msg) - 1); | 1212 WriteLog(msg, sizeof(msg) - 1); |
| 1180 #else | 1213 #else |
| 1181 // Write crash dump id to stderr. | 1214 // Write crash dump id to stderr. |
| 1182 static const char msg[] = "Crash dump id: "; | 1215 static const char msg[] = "Crash dump id: "; |
| 1183 WriteLog(msg, sizeof(msg) - 1); | 1216 WriteLog(msg, sizeof(msg) - 1); |
| 1184 WriteLog(buf, my_strlen(buf)); | 1217 WriteLog(buf, my_strlen(buf)); |
| 1185 WriteNewline(); | 1218 WriteNewline(); |
| 1186 | 1219 |
| 1187 // Write crash dump id to crash log as: seconds_since_epoch,crash_id | 1220 // Write crash dump id to crash log as: seconds_since_epoch,crash_id |
| 1188 struct kernel_timeval tv; | 1221 struct kernel_timeval tv; |
| 1189 if (g_crash_log_path && !sys_gettimeofday(&tv, NULL)) { | 1222 if (g_crash_log_path && !sys_gettimeofday(&tv, nullptr)) { |
| 1190 uint64_t time = kernel_timeval_to_ms(&tv) / 1000; | 1223 uint64_t time = kernel_timeval_to_ms(&tv) / 1000; |
| 1191 char time_str[kUint64StringSize]; | 1224 char time_str[kUint64StringSize]; |
| 1192 const unsigned time_len = my_uint64_len(time); | 1225 const unsigned time_len = my_uint64_len(time); |
| 1193 my_uint64tos(time_str, time, time_len); | 1226 my_uint64tos(time_str, time, time_len); |
| 1194 | 1227 |
| 1195 const int kLogOpenFlags = O_CREAT | O_WRONLY | O_APPEND | O_CLOEXEC; | 1228 const int kLogOpenFlags = O_CREAT | O_WRONLY | O_APPEND | O_CLOEXEC; |
| 1196 int log_fd = sys_open(g_crash_log_path, kLogOpenFlags, 0600); | 1229 int log_fd = sys_open(g_crash_log_path, kLogOpenFlags, 0600); |
| 1197 if (log_fd > 0) { | 1230 if (log_fd > 0) { |
| 1198 sys_write(log_fd, time_str, time_len); | 1231 sys_write(log_fd, time_str, time_len); |
| 1199 sys_write(log_fd, ",", 1); | 1232 sys_write(log_fd, ",", 1); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1234 return "chrome-crash-unknown-process"; | 1267 return "chrome-crash-unknown-process"; |
| 1235 } | 1268 } |
| 1236 #endif | 1269 #endif |
| 1237 | 1270 |
| 1238 void HandleCrashDump(const BreakpadInfo& info) { | 1271 void HandleCrashDump(const BreakpadInfo& info) { |
| 1239 int dumpfd; | 1272 int dumpfd; |
| 1240 bool keep_fd = false; | 1273 bool keep_fd = false; |
| 1241 size_t dump_size; | 1274 size_t dump_size; |
| 1242 uint8_t* dump_data; | 1275 uint8_t* dump_data; |
| 1243 google_breakpad::PageAllocator allocator; | 1276 google_breakpad::PageAllocator allocator; |
| 1244 const char* exe_buf = NULL; | 1277 const char* exe_buf = nullptr; |
| 1245 | 1278 |
| 1246 if (GetCrashReporterClient()->HandleCrashDump(info.filename)) { | 1279 if (GetCrashReporterClient()->HandleCrashDump(info.filename)) { |
| 1247 return; | 1280 return; |
| 1248 } | 1281 } |
| 1249 | 1282 |
| 1250 #if defined(OS_CHROMEOS) | 1283 #if defined(OS_CHROMEOS) |
| 1251 // Grab the crashing process' name now, when it should still be available. | 1284 // Grab the crashing process' name now, when it should still be available. |
| 1252 // If we try to do this later in our grandchild the crashing process has | 1285 // If we try to do this later in our grandchild the crashing process has |
| 1253 // already terminated. | 1286 // already terminated. |
| 1254 exe_buf = GetCrashingProcessName(info, &allocator); | 1287 exe_buf = GetCrashingProcessName(info, &allocator); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1429 writer.AddBoundary(); | 1462 writer.AddBoundary(); |
| 1430 writer.AddPairString( | 1463 writer.AddPairString( |
| 1431 android_build_fp, android_build_info->android_build_fp()); | 1464 android_build_fp, android_build_info->android_build_fp()); |
| 1432 writer.AddBoundary(); | 1465 writer.AddBoundary(); |
| 1433 writer.AddPairString(device, android_build_info->device()); | 1466 writer.AddPairString(device, android_build_info->device()); |
| 1434 writer.AddBoundary(); | 1467 writer.AddBoundary(); |
| 1435 writer.AddPairString(model, android_build_info->model()); | 1468 writer.AddPairString(model, android_build_info->model()); |
| 1436 writer.AddBoundary(); | 1469 writer.AddBoundary(); |
| 1437 writer.AddPairString(brand, android_build_info->brand()); | 1470 writer.AddPairString(brand, android_build_info->brand()); |
| 1438 writer.AddBoundary(); | 1471 writer.AddBoundary(); |
| 1439 if (android_build_info->java_exception_info() != NULL) { | 1472 if (android_build_info->java_exception_info() != nullptr) { |
| 1440 writer.AddPairString(exception_info, | 1473 writer.AddPairString(exception_info, |
| 1441 android_build_info->java_exception_info()); | 1474 android_build_info->java_exception_info()); |
| 1442 writer.AddBoundary(); | 1475 writer.AddBoundary(); |
| 1443 } | 1476 } |
| 1444 #endif | 1477 #endif |
| 1445 writer.Flush(); | 1478 writer.Flush(); |
| 1446 } | 1479 } |
| 1447 | 1480 |
| 1448 if (info.process_start_time > 0) { | 1481 if (info.process_start_time > 0) { |
| 1449 struct kernel_timeval tv; | 1482 struct kernel_timeval tv; |
| 1450 if (!sys_gettimeofday(&tv, NULL)) { | 1483 if (!sys_gettimeofday(&tv, nullptr)) { |
| 1451 uint64_t time = kernel_timeval_to_ms(&tv); | 1484 uint64_t time = kernel_timeval_to_ms(&tv); |
| 1452 if (time > info.process_start_time) { | 1485 if (time > info.process_start_time) { |
| 1453 time -= info.process_start_time; | 1486 time -= info.process_start_time; |
| 1454 char time_str[kUint64StringSize]; | 1487 char time_str[kUint64StringSize]; |
| 1455 const unsigned time_len = my_uint64_len(time); | 1488 const unsigned time_len = my_uint64_len(time); |
| 1456 my_uint64tos(time_str, time, time_len); | 1489 my_uint64tos(time_str, time, time_len); |
| 1457 | 1490 |
| 1458 static const char process_time_msg[] = "ptime"; | 1491 static const char process_time_msg[] = "ptime"; |
| 1459 writer.AddPairData(process_time_msg, sizeof(process_time_msg) - 1, | 1492 writer.AddPairData(process_time_msg, sizeof(process_time_msg) - 1, |
| 1460 time_str, time_len); | 1493 time_str, time_len); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1599 // Helper process. | 1632 // Helper process. |
| 1600 if (upload_child > 0) { | 1633 if (upload_child > 0) { |
| 1601 IGNORE_RET(sys_close(fds[1])); | 1634 IGNORE_RET(sys_close(fds[1])); |
| 1602 | 1635 |
| 1603 const size_t kCrashIdLength = 16; | 1636 const size_t kCrashIdLength = 16; |
| 1604 char id_buf[kCrashIdLength + 1]; | 1637 char id_buf[kCrashIdLength + 1]; |
| 1605 size_t bytes_read = | 1638 size_t bytes_read = |
| 1606 WaitForCrashReportUploadProcess(fds[0], kCrashIdLength, id_buf); | 1639 WaitForCrashReportUploadProcess(fds[0], kCrashIdLength, id_buf); |
| 1607 HandleCrashReportId(id_buf, bytes_read, kCrashIdLength); | 1640 HandleCrashReportId(id_buf, bytes_read, kCrashIdLength); |
| 1608 | 1641 |
| 1609 if (sys_waitpid(upload_child, NULL, WNOHANG) == 0) { | 1642 if (sys_waitpid(upload_child, nullptr, WNOHANG) == 0) { |
| 1610 // Upload process is still around, kill it. | 1643 // Upload process is still around, kill it. |
| 1611 sys_kill(upload_child, SIGKILL); | 1644 sys_kill(upload_child, SIGKILL); |
| 1612 } | 1645 } |
| 1613 } | 1646 } |
| 1614 } | 1647 } |
| 1615 | 1648 |
| 1616 // Helper process. | 1649 // Helper process. |
| 1617 IGNORE_RET(sys_unlink(info.filename)); | 1650 IGNORE_RET(sys_unlink(info.filename)); |
| 1618 #if defined(ADDRESS_SANITIZER) | 1651 #if defined(ADDRESS_SANITIZER) |
| 1619 IGNORE_RET(sys_unlink(info.log_filename)); | 1652 IGNORE_RET(sys_unlink(info.log_filename)); |
| 1620 #endif | 1653 #endif |
| 1621 IGNORE_RET(sys_unlink(temp_file)); | 1654 IGNORE_RET(sys_unlink(temp_file)); |
| 1622 sys__exit(0); | 1655 sys__exit(0); |
| 1623 } | 1656 } |
| 1624 | 1657 |
| 1625 // Main browser process. | 1658 // Main browser process. |
| 1626 if (child <= 0) | 1659 if (child <= 0) |
| 1627 return; | 1660 return; |
| 1628 (void) HANDLE_EINTR(sys_waitpid(child, NULL, 0)); | 1661 (void) HANDLE_EINTR(sys_waitpid(child, nullptr, 0)); |
| 1629 } | 1662 } |
| 1630 | 1663 |
| 1631 void InitCrashReporter(const std::string& process_type) { | 1664 void InitCrashReporter(const std::string& process_type) { |
| 1632 #if defined(OS_ANDROID) | 1665 #if defined(OS_ANDROID) |
| 1633 // This will guarantee that the BuildInfo has been initialized and subsequent | 1666 // This will guarantee that the BuildInfo has been initialized and subsequent |
| 1634 // calls will not require memory allocation. | 1667 // calls will not require memory allocation. |
| 1635 base::android::BuildInfo::GetInstance(); | 1668 base::android::BuildInfo::GetInstance(); |
| 1636 | 1669 |
| 1637 // Handler registration is LIFO. Install the microdump handler first, such | 1670 // Handler registration is LIFO. Install the microdump handler first, such |
| 1638 // that if conventional minidump crash reporting is enabled below, it takes | 1671 // that if conventional minidump crash reporting is enabled below, it takes |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1708 } | 1741 } |
| 1709 } | 1742 } |
| 1710 } | 1743 } |
| 1711 #endif // OS_ANDROID | 1744 #endif // OS_ANDROID |
| 1712 | 1745 |
| 1713 bool IsCrashReporterEnabled() { | 1746 bool IsCrashReporterEnabled() { |
| 1714 return g_is_crash_reporter_enabled; | 1747 return g_is_crash_reporter_enabled; |
| 1715 } | 1748 } |
| 1716 | 1749 |
| 1717 } // namespace breakpad | 1750 } // namespace breakpad |
| OLD | NEW |