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/content/app/breakpad_linux.h" | 8 #include "components/crash/content/app/breakpad_linux.h" |
| 9 | 9 |
| 10 #include <fcntl.h> | 10 #include <fcntl.h> |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 103 | 103 |
| 104 #if defined(OS_ANDROID) | 104 #if defined(OS_ANDROID) |
| 105 #define G_DUMPS_SUPPRESSED_MAGIC 0x5AFECEDE | 105 #define G_DUMPS_SUPPRESSED_MAGIC 0x5AFECEDE |
| 106 uint32_t g_dumps_suppressed = 0; | 106 uint32_t g_dumps_suppressed = 0; |
| 107 char* g_process_type = nullptr; | 107 char* g_process_type = nullptr; |
| 108 ExceptionHandler* g_microdump = nullptr; | 108 ExceptionHandler* g_microdump = nullptr; |
| 109 int g_signal_code_pipe_fd = -1; | 109 int g_signal_code_pipe_fd = -1; |
| 110 | 110 |
| 111 class MicrodumpInfo { | 111 class MicrodumpInfo { |
| 112 public: | 112 public: |
| 113 MicrodumpInfo() | 113 MicrodumpInfo() : microdump_gpu_fingerprint_(nullptr) {} |
| 114 : microdump_build_fingerprint_(nullptr), | |
| 115 microdump_product_info_(nullptr), | |
| 116 microdump_gpu_fingerprint_(nullptr), | |
| 117 microdump_process_type_(nullptr), | |
| 118 skip_dump_if_principal_mapping_not_referenced_(false), | |
| 119 address_within_principal_mapping_(0ul), | |
| 120 should_sanitize_dumps_(false) {} | |
| 121 | 114 |
| 122 // The order in which SetGpuFingerprint and Initialize are called | 115 // The order in which SetGpuFingerprint and Initialize are called |
| 123 // may be dependent on the timing of the availability of GPU | 116 // may be dependent on the timing of the availability of GPU |
| 124 // information. For this reason, they can be called in either order, | 117 // information. For this reason, they can be called in either order, |
| 125 // resulting in the same effect. | 118 // resulting in the same effect. |
| 126 // | 119 // |
| 127 // The following restrictions apply, however: | 120 // The following restrictions apply, however: |
| 128 // * Both methods must be called from the same thread. | 121 // * Both methods must be called from the same thread. |
| 129 // * Both methods must be called at most once. | 122 // * Both methods must be called at most once. |
| 130 // | 123 // |
| 131 // Microdumps will only be generated if Initialize is called. If | 124 // Microdumps will only be generated if Initialize is called. If |
| 132 // SetGpuFingerprint has not been called called at the point at | 125 // SetGpuFingerprint has not been called called at the point at |
| 133 // which a microdump is generated, then the GPU fingerprint will be | 126 // which a microdump is generated, then the GPU fingerprint will be |
| 134 // UNKNOWN. | 127 // UNKNOWN. |
| 135 void SetGpuFingerprint(const std::string& gpu_fingerprint); | 128 void SetGpuFingerprintForMicrodump(const std::string& gpu_fingerprint); |
| 136 void SetSkipDumpIfPrincipalMappingNotReferenced( | |
| 137 uintptr_t address_within_principal_mapping); | |
| 138 void SetShouldSanitizeDumps(bool should_sanitize_dumps); | |
| 139 void UpdateMinidumpDescriptor(MinidumpDescriptor* minidump_descriptor); | |
| 140 void UpdateExceptionHandlers(); | |
| 141 void Initialize(const std::string& process_type, | 129 void Initialize(const std::string& process_type, |
| 142 const char* product_name, | 130 const char* product_name, |
| 143 const char* product_version, | 131 const char* product_version, |
| 144 const char* android_build_fp); | 132 const char* android_build_fp, |
| 133 const SanitizationInfo& sanitization_info); | |
| 145 | 134 |
| 146 private: | 135 private: |
| 147 base::ThreadChecker thread_checker_; | 136 base::ThreadChecker thread_checker_; |
| 148 const char* microdump_build_fingerprint_; | |
| 149 const char* microdump_product_info_; | |
| 150 const char* microdump_gpu_fingerprint_; | 137 const char* microdump_gpu_fingerprint_; |
| 151 const char* microdump_process_type_; | |
| 152 bool skip_dump_if_principal_mapping_not_referenced_; | |
| 153 uintptr_t address_within_principal_mapping_; | |
| 154 bool should_sanitize_dumps_; | |
| 155 }; | 138 }; |
| 156 | 139 |
| 140 void SetMinidumpSanitizationFields(MinidumpDescriptor* minidump_descriptor, | |
| 141 const SanitizationInfo& sanitization_info); | |
| 142 | |
| 157 base::LazyInstance<MicrodumpInfo> g_microdump_info = | 143 base::LazyInstance<MicrodumpInfo> g_microdump_info = |
| 158 LAZY_INSTANCE_INITIALIZER; | 144 LAZY_INSTANCE_INITIALIZER; |
| 159 | 145 |
| 160 #endif | 146 #endif |
| 161 | 147 |
| 162 CrashKeyStorage* g_crash_keys = nullptr; | 148 CrashKeyStorage* g_crash_keys = nullptr; |
| 163 | 149 |
| 164 // Writes the value |v| as 16 hex characters to the memory pointed at by | 150 // Writes the value |v| as 16 hex characters to the memory pointed at by |
| 165 // |output|. | 151 // |output|. |
| 166 void write_uint64_hex(char* output, uint64_t v) { | 152 void write_uint64_hex(char* output, uint64_t v) { |
| (...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 773 void __asan_set_error_report_callback(void (*cb)(const char*)); | 759 void __asan_set_error_report_callback(void (*cb)(const char*)); |
| 774 | 760 |
| 775 extern "C" | 761 extern "C" |
| 776 void AsanLinuxBreakpadCallback(const char* report) { | 762 void AsanLinuxBreakpadCallback(const char* report) { |
| 777 g_asan_report_str = report; | 763 g_asan_report_str = report; |
| 778 // Send minidump here. | 764 // Send minidump here. |
| 779 g_breakpad->SimulateSignalDelivery(SIGKILL); | 765 g_breakpad->SimulateSignalDelivery(SIGKILL); |
| 780 } | 766 } |
| 781 #endif | 767 #endif |
| 782 | 768 |
| 769 #if defined(OS_ANDROID) | |
| 770 void EnableCrashDumping(bool unattended, | |
| 771 const SanitizationInfo& sanitization_info) { | |
| 772 #else | |
| 783 void EnableCrashDumping(bool unattended) { | 773 void EnableCrashDumping(bool unattended) { |
| 774 #endif // defined(OS_ANDROID) | |
| 784 g_is_crash_reporter_enabled = true; | 775 g_is_crash_reporter_enabled = true; |
| 785 | 776 |
| 786 base::FilePath tmp_path("/tmp"); | 777 base::FilePath tmp_path("/tmp"); |
| 787 PathService::Get(base::DIR_TEMP, &tmp_path); | 778 PathService::Get(base::DIR_TEMP, &tmp_path); |
| 788 | 779 |
| 789 base::FilePath dumps_path(tmp_path); | 780 base::FilePath dumps_path(tmp_path); |
| 790 if (GetCrashReporterClient()->GetCrashDumpLocation(&dumps_path)) { | 781 if (GetCrashReporterClient()->GetCrashDumpLocation(&dumps_path)) { |
| 791 base::FilePath logfile = | 782 base::FilePath logfile = |
| 792 dumps_path.Append(GetCrashReporterClient()->GetReporterLogFilename()); | 783 dumps_path.Append(GetCrashReporterClient()->GetReporterLogFilename()); |
| 793 std::string logfile_str = logfile.value(); | 784 std::string logfile_str = logfile.value(); |
| 794 const size_t crash_log_path_len = logfile_str.size() + 1; | 785 const size_t crash_log_path_len = logfile_str.size() + 1; |
| 795 g_crash_log_path = new char[crash_log_path_len]; | 786 g_crash_log_path = new char[crash_log_path_len]; |
| 796 strncpy(g_crash_log_path, logfile_str.c_str(), crash_log_path_len); | 787 strncpy(g_crash_log_path, logfile_str.c_str(), crash_log_path_len); |
| 797 } | 788 } |
| 798 DCHECK(!g_breakpad); | 789 DCHECK(!g_breakpad); |
| 799 MinidumpDescriptor minidump_descriptor(dumps_path.value()); | 790 MinidumpDescriptor minidump_descriptor(dumps_path.value()); |
| 800 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 791 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 801 switches::kFullMemoryCrashReport)) { | 792 switches::kFullMemoryCrashReport)) { |
| 802 minidump_descriptor.set_size_limit(-1); // unlimited. | 793 minidump_descriptor.set_size_limit(-1); // unlimited. |
| 803 } else { | 794 } else { |
| 804 minidump_descriptor.set_size_limit(kMaxMinidumpFileSize); | 795 minidump_descriptor.set_size_limit(kMaxMinidumpFileSize); |
| 805 } | 796 } |
| 806 #if defined(OS_ANDROID) | 797 #if defined(OS_ANDROID) |
| 807 unattended = true; // Android never uploads directly. | 798 unattended = true; // Android never uploads directly. |
| 808 g_microdump_info.Get().UpdateMinidumpDescriptor(&minidump_descriptor); | 799 SetMinidumpSanitizationFields(&minidump_descriptor, sanitization_info); |
| 809 #endif | 800 #endif |
| 810 if (unattended) { | 801 if (unattended) { |
| 811 g_breakpad = new ExceptionHandler( | 802 g_breakpad = new ExceptionHandler( |
| 812 minidump_descriptor, | 803 minidump_descriptor, |
| 813 #if defined(OS_ANDROID) | 804 #if defined(OS_ANDROID) |
| 814 ShouldGenerateDump, | 805 ShouldGenerateDump, |
| 815 #else | 806 #else |
| 816 nullptr, | 807 nullptr, |
| 817 #endif | 808 #endif |
| 818 CrashDoneNoUpload, | 809 CrashDoneNoUpload, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 876 info.distro_length = 0; | 867 info.distro_length = 0; |
| 877 info.upload = false; | 868 info.upload = false; |
| 878 info.process_start_time = g_process_start_time; | 869 info.process_start_time = g_process_start_time; |
| 879 info.pid = g_pid; | 870 info.pid = g_pid; |
| 880 info.crash_keys = g_crash_keys; | 871 info.crash_keys = g_crash_keys; |
| 881 HandleCrashDump(info); | 872 HandleCrashDump(info); |
| 882 return FinalizeCrashDoneAndroid(false /* is_browser_process */); | 873 return FinalizeCrashDoneAndroid(false /* is_browser_process */); |
| 883 } | 874 } |
| 884 | 875 |
| 885 void EnableNonBrowserCrashDumping(const std::string& process_type, | 876 void EnableNonBrowserCrashDumping(const std::string& process_type, |
| 886 int minidump_fd) { | 877 int minidump_fd, |
| 878 const SanitizationInfo& sanitization_info) { | |
| 887 // This will guarantee that the BuildInfo has been initialized and subsequent | 879 // This will guarantee that the BuildInfo has been initialized and subsequent |
| 888 // calls will not require memory allocation. | 880 // calls will not require memory allocation. |
| 889 base::android::BuildInfo::GetInstance(); | 881 base::android::BuildInfo::GetInstance(); |
| 890 SetClientIdFromCommandLine(*base::CommandLine::ForCurrentProcess()); | 882 SetClientIdFromCommandLine(*base::CommandLine::ForCurrentProcess()); |
| 891 | 883 |
| 892 // On Android, the current sandboxing uses process isolation, in which the | 884 // On Android, the current sandboxing uses process isolation, in which the |
| 893 // child process runs with a different UID. That breaks the normal crash | 885 // child process runs with a different UID. That breaks the normal crash |
| 894 // reporting where the browser process generates the minidump by inspecting | 886 // reporting where the browser process generates the minidump by inspecting |
| 895 // the child process. This is because the browser process now does not have | 887 // the child process. This is because the browser process now does not have |
| 896 // the permission to access the states of the child process (as it has a | 888 // the permission to access the states of the child process (as it has a |
| 897 // different UID). | 889 // different UID). |
| 898 // TODO(jcivelli): http://b/issue?id=6776356 we should use a watchdog | 890 // TODO(jcivelli): http://b/issue?id=6776356 we should use a watchdog |
| 899 // process forked from the renderer process that generates the minidump. | 891 // process forked from the renderer process that generates the minidump. |
| 900 if (minidump_fd == -1) { | 892 if (minidump_fd == -1) { |
| 901 LOG(ERROR) << "Minidump file descriptor not found, crash reporting will " | 893 LOG(ERROR) << "Minidump file descriptor not found, crash reporting will " |
| 902 " not work."; | 894 " not work."; |
| 903 return; | 895 return; |
| 904 } | 896 } |
| 905 SetProcessStartTime(); | 897 SetProcessStartTime(); |
| 906 g_pid = getpid(); | 898 g_pid = getpid(); |
| 907 | 899 |
| 908 g_is_crash_reporter_enabled = true; | 900 g_is_crash_reporter_enabled = true; |
| 909 // Save the process type (it is leaked). | 901 // Save the process type (it is leaked). |
| 910 const size_t process_type_len = process_type.size() + 1; | 902 const size_t process_type_len = process_type.size() + 1; |
| 911 g_process_type = new char[process_type_len]; | 903 g_process_type = new char[process_type_len]; |
| 912 strncpy(g_process_type, process_type.c_str(), process_type_len); | 904 strncpy(g_process_type, process_type.c_str(), process_type_len); |
| 913 | 905 |
| 914 MinidumpDescriptor descriptor(minidump_fd); | 906 MinidumpDescriptor descriptor(minidump_fd); |
| 915 g_microdump_info.Get().UpdateMinidumpDescriptor(&descriptor); | 907 SetMinidumpSanitizationFields(&descriptor, sanitization_info); |
| 916 g_breakpad = | 908 g_breakpad = |
| 917 new ExceptionHandler(descriptor, ShouldGenerateDump, | 909 new ExceptionHandler(descriptor, ShouldGenerateDump, |
| 918 CrashDoneInProcessNoUpload, nullptr, true, -1); | 910 CrashDoneInProcessNoUpload, nullptr, true, -1); |
| 919 } | 911 } |
| 920 | 912 |
| 921 void MicrodumpInfo::SetGpuFingerprint(const std::string& gpu_fingerprint) { | 913 void MicrodumpInfo::SetGpuFingerprintForMicrodump( |
| 914 const std::string& gpu_fingerprint) { | |
| 922 DCHECK(thread_checker_.CalledOnValidThread()); | 915 DCHECK(thread_checker_.CalledOnValidThread()); |
| 923 DCHECK(!microdump_gpu_fingerprint_); | 916 DCHECK(!microdump_gpu_fingerprint_); |
| 924 microdump_gpu_fingerprint_ = strdup(gpu_fingerprint.c_str()); | 917 microdump_gpu_fingerprint_ = strdup(gpu_fingerprint.c_str()); |
| 925 ANNOTATE_LEAKING_OBJECT_PTR(microdump_gpu_fingerprint_); | 918 ANNOTATE_LEAKING_OBJECT_PTR(microdump_gpu_fingerprint_); |
| 926 | 919 |
| 927 UpdateExceptionHandlers(); | 920 if (g_microdump) { |
| 921 MinidumpDescriptor descriptor(g_microdump->minidump_descriptor()); | |
| 922 descriptor.microdump_extra_info()->gpu_fingerprint = | |
| 923 microdump_gpu_fingerprint_; | |
| 924 g_microdump->set_minidump_descriptor(descriptor); | |
| 925 } | |
| 928 } | 926 } |
| 929 | 927 |
| 930 void MicrodumpInfo::SetSkipDumpIfPrincipalMappingNotReferenced( | 928 void SetMinidumpSanitizationFields(MinidumpDescriptor* minidump_descriptor, |
| 931 uintptr_t address_within_principal_mapping) { | 929 const SanitizationInfo& sanitization_info) { |
| 932 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 933 skip_dump_if_principal_mapping_not_referenced_ = true; | |
| 934 address_within_principal_mapping_ = address_within_principal_mapping; | |
| 935 | |
| 936 UpdateExceptionHandlers(); | |
| 937 } | |
| 938 | |
| 939 void MicrodumpInfo::SetShouldSanitizeDumps(bool should_sanitize_dumps) { | |
| 940 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 941 should_sanitize_dumps_ = should_sanitize_dumps; | |
| 942 | |
| 943 UpdateExceptionHandlers(); | |
| 944 } | |
| 945 | |
| 946 void MicrodumpInfo::UpdateMinidumpDescriptor( | |
| 947 MinidumpDescriptor* minidump_descriptor) { | |
| 948 google_breakpad::MicrodumpExtraInfo* microdump_extra_info = | |
| 949 minidump_descriptor->microdump_extra_info(); | |
| 950 | |
| 951 minidump_descriptor->set_skip_dump_if_principal_mapping_not_referenced( | 930 minidump_descriptor->set_skip_dump_if_principal_mapping_not_referenced( |
| 952 skip_dump_if_principal_mapping_not_referenced_); | 931 sanitization_info.skip_dump_if_principal_mapping_not_referenced); |
| 953 minidump_descriptor->set_address_within_principal_mapping( | 932 minidump_descriptor->set_address_within_principal_mapping( |
| 954 address_within_principal_mapping_); | 933 sanitization_info.address_within_principal_mapping); |
| 955 minidump_descriptor->set_sanitize_stacks(should_sanitize_dumps_); | 934 minidump_descriptor->set_sanitize_stacks( |
| 956 | 935 sanitization_info.should_sanitize_dumps); |
| 957 microdump_extra_info->gpu_fingerprint = microdump_gpu_fingerprint_; | |
| 958 microdump_extra_info->product_info = microdump_product_info_; | |
| 959 microdump_extra_info->process_type = microdump_process_type_; | |
| 960 microdump_extra_info->build_fingerprint = microdump_build_fingerprint_; | |
| 961 } | |
| 962 | |
| 963 void MicrodumpInfo::UpdateExceptionHandlers() { | |
| 964 if (g_breakpad) { | |
| 965 MinidumpDescriptor descriptor(g_breakpad->minidump_descriptor()); | |
| 966 UpdateMinidumpDescriptor(&descriptor); | |
| 967 g_breakpad->set_minidump_descriptor(descriptor); | |
| 968 } | |
| 969 if (g_microdump) { | |
| 970 MinidumpDescriptor descriptor(g_microdump->minidump_descriptor()); | |
| 971 UpdateMinidumpDescriptor(&descriptor); | |
| 972 g_microdump->set_minidump_descriptor(descriptor); | |
| 973 } | |
| 974 } | 936 } |
| 975 | 937 |
| 976 void MicrodumpInfo::Initialize(const std::string& process_type, | 938 void MicrodumpInfo::Initialize(const std::string& process_type, |
| 977 const char* product_name, | 939 const char* product_name, |
| 978 const char* product_version, | 940 const char* product_version, |
| 979 const char* android_build_fp) { | 941 const char* android_build_fp, |
| 942 const SanitizationInfo& sanitization_info) { | |
| 980 DCHECK(thread_checker_.CalledOnValidThread()); | 943 DCHECK(thread_checker_.CalledOnValidThread()); |
| 981 DCHECK(!g_microdump); | 944 DCHECK(!g_microdump); |
| 982 // |process_type| for webview's browser process is kBrowserProcessType or | 945 // |process_type| for webview's browser process is kBrowserProcessType or |
| 983 // kWebViewSingleProcessType. |process_type| for chrome's browser process is | 946 // kWebViewSingleProcessType. |process_type| for chrome's browser process is |
| 984 // an empty string. | 947 // an empty string. |
| 985 bool is_browser_process = process_type.empty() || | 948 bool is_browser_process = process_type.empty() || |
| 986 process_type == kWebViewSingleProcessType || | 949 process_type == kWebViewSingleProcessType || |
| 987 process_type == kBrowserProcessType; | 950 process_type == kBrowserProcessType; |
| 988 | 951 |
| 989 MinidumpDescriptor descriptor(MinidumpDescriptor::kMicrodumpOnConsole); | 952 MinidumpDescriptor descriptor(MinidumpDescriptor::kMicrodumpOnConsole); |
| 953 google_breakpad::MicrodumpExtraInfo* microdump_extra_info = | |
| 954 descriptor.microdump_extra_info(); | |
| 990 | 955 |
| 991 if (product_name && product_version) { | 956 if (product_name && product_version) { |
| 992 microdump_product_info_ = | 957 microdump_extra_info->product_info = |
|
Tobias Sargeant
2017/02/24 11:36:24
It looks like you would need ANNOTATE_LEAKING_OBJE
gsennton
2017/02/24 13:44:27
Done.
| |
| 993 strdup((product_name + std::string(":") + product_version).c_str()); | 958 strdup((product_name + std::string(":") + product_version).c_str()); |
| 994 ANNOTATE_LEAKING_OBJECT_PTR(microdump_product_info_); | |
| 995 } | 959 } |
| 996 | 960 |
| 997 microdump_process_type_ = | 961 microdump_extra_info->process_type = |
| 998 strdup(process_type.empty() ? kBrowserProcessType : process_type.c_str()); | 962 strdup(process_type.empty() ? kBrowserProcessType : process_type.c_str()); |
| 999 ANNOTATE_LEAKING_OBJECT_PTR(microdump_process_type_); | |
| 1000 | 963 |
| 1001 if (android_build_fp) { | 964 if (android_build_fp) { |
| 1002 microdump_build_fingerprint_ = strdup(android_build_fp); | 965 microdump_extra_info->build_fingerprint = strdup(android_build_fp); |
| 1003 ANNOTATE_LEAKING_OBJECT_PTR(microdump_build_fingerprint_); | |
| 1004 } | 966 } |
| 1005 | 967 |
| 1006 UpdateMinidumpDescriptor(&descriptor); | 968 SetMinidumpSanitizationFields(&descriptor, sanitization_info); |
| 969 microdump_extra_info->gpu_fingerprint = microdump_gpu_fingerprint_; | |
| 1007 | 970 |
| 1008 g_microdump = | 971 g_microdump = |
| 1009 new ExceptionHandler(descriptor, ShouldGenerateDump, MicrodumpCrashDone, | 972 new ExceptionHandler(descriptor, ShouldGenerateDump, MicrodumpCrashDone, |
| 1010 reinterpret_cast<void*>(is_browser_process), | 973 reinterpret_cast<void*>(is_browser_process), |
| 1011 true, // Install handlers. | 974 true, // Install handlers. |
| 1012 -1); // Server file descriptor. -1 for in-process. | 975 -1); // Server file descriptor. -1 for in-process. |
| 1013 | 976 |
| 1014 if (process_type != kWebViewSingleProcessType && | 977 if (process_type != kWebViewSingleProcessType && |
| 1015 process_type != kBrowserProcessType && | 978 process_type != kBrowserProcessType && |
| 1016 !process_type.empty()) { | 979 !process_type.empty()) { |
| (...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1923 IGNORE_RET(sys_unlink(temp_file)); | 1886 IGNORE_RET(sys_unlink(temp_file)); |
| 1924 sys__exit(0); | 1887 sys__exit(0); |
| 1925 } | 1888 } |
| 1926 | 1889 |
| 1927 // Main browser process. | 1890 // Main browser process. |
| 1928 if (child <= 0) | 1891 if (child <= 0) |
| 1929 return; | 1892 return; |
| 1930 (void) HANDLE_EINTR(sys_waitpid(child, nullptr, 0)); | 1893 (void) HANDLE_EINTR(sys_waitpid(child, nullptr, 0)); |
| 1931 } | 1894 } |
| 1932 | 1895 |
| 1896 #if defined(OS_ANDROID) | |
| 1897 // In Android WebView, microdumps are generated conditionally (depending on the | |
| 1898 // cause of the crash) and can be sanitized to prevent exposing unnecessary data | |
| 1899 // from the embedding application. | |
| 1933 void InitCrashReporter(const std::string& process_type) { | 1900 void InitCrashReporter(const std::string& process_type) { |
| 1901 SanitizationInfo sanitization_info; | |
| 1902 InitCrashReporter(process_type, sanitization_info); | |
| 1903 } | |
| 1904 | |
| 1905 void InitCrashReporter(const std::string& process_type, | |
| 1906 const SanitizationInfo& sanitization_info) { | |
| 1907 #else | |
| 1908 void InitCrashReporter(const std::string& process_type) { | |
| 1909 #endif // defined(OS_ANDROID) | |
| 1934 // The maximum lengths specified by breakpad include the trailing NULL, so the | 1910 // The maximum lengths specified by breakpad include the trailing NULL, so the |
| 1935 // actual length of the chunk is one less. | 1911 // actual length of the chunk is one less. |
| 1936 static_assert(crash_keys::kChunkMaxLength == 63, "kChunkMaxLength mismatch"); | 1912 static_assert(crash_keys::kChunkMaxLength == 63, "kChunkMaxLength mismatch"); |
| 1937 static_assert(crash_keys::kSmallSize <= crash_keys::kChunkMaxLength, | 1913 static_assert(crash_keys::kSmallSize <= crash_keys::kChunkMaxLength, |
| 1938 "crash key chunk size too small"); | 1914 "crash key chunk size too small"); |
| 1939 #if defined(OS_ANDROID) | 1915 #if defined(OS_ANDROID) |
| 1940 // This will guarantee that the BuildInfo has been initialized and subsequent | 1916 // This will guarantee that the BuildInfo has been initialized and subsequent |
| 1941 // calls will not require memory allocation. | 1917 // calls will not require memory allocation. |
| 1942 base::android::BuildInfo::GetInstance(); | 1918 base::android::BuildInfo::GetInstance(); |
| 1943 | 1919 |
| 1944 // Handler registration is LIFO. Install the microdump handler first, such | 1920 // Handler registration is LIFO. Install the microdump handler first, such |
| 1945 // that if conventional minidump crash reporting is enabled below, it takes | 1921 // that if conventional minidump crash reporting is enabled below, it takes |
| 1946 // precedence (i.e. its handler is run first) over the microdump handler. | 1922 // precedence (i.e. its handler is run first) over the microdump handler. |
| 1947 InitMicrodumpCrashHandlerIfNecessary(process_type); | 1923 InitMicrodumpCrashHandlerIfNecessary(process_type, sanitization_info); |
| 1948 #endif | 1924 #endif |
| 1949 // Determine the process type and take appropriate action. | 1925 // Determine the process type and take appropriate action. |
| 1950 const base::CommandLine& parsed_command_line = | 1926 const base::CommandLine& parsed_command_line = |
| 1951 *base::CommandLine::ForCurrentProcess(); | 1927 *base::CommandLine::ForCurrentProcess(); |
| 1952 if (parsed_command_line.HasSwitch(switches::kDisableBreakpad)) | 1928 if (parsed_command_line.HasSwitch(switches::kDisableBreakpad)) |
| 1953 return; | 1929 return; |
| 1954 | 1930 |
| 1955 if (process_type.empty()) { | 1931 if (process_type.empty()) { |
| 1956 bool enable_breakpad = GetCrashReporterClient()->GetCollectStatsConsent() || | 1932 bool enable_breakpad = GetCrashReporterClient()->GetCollectStatsConsent() || |
| 1957 GetCrashReporterClient()->IsRunningUnattended(); | 1933 GetCrashReporterClient()->IsRunningUnattended(); |
| 1958 enable_breakpad &= | 1934 enable_breakpad &= |
| 1959 !parsed_command_line.HasSwitch(switches::kDisableBreakpad); | 1935 !parsed_command_line.HasSwitch(switches::kDisableBreakpad); |
| 1960 if (!enable_breakpad) { | 1936 if (!enable_breakpad) { |
| 1961 enable_breakpad = parsed_command_line.HasSwitch( | 1937 enable_breakpad = parsed_command_line.HasSwitch( |
| 1962 switches::kEnableCrashReporterForTesting); | 1938 switches::kEnableCrashReporterForTesting); |
| 1963 } | 1939 } |
| 1964 if (!enable_breakpad) { | 1940 if (!enable_breakpad) { |
| 1965 VLOG(1) << "Breakpad disabled"; | 1941 VLOG(1) << "Breakpad disabled"; |
| 1966 return; | 1942 return; |
| 1967 } | 1943 } |
| 1968 | 1944 |
| 1969 InitCrashKeys(); | 1945 InitCrashKeys(); |
| 1946 #if defined(OS_ANDROID) | |
| 1947 EnableCrashDumping(GetCrashReporterClient()->IsRunningUnattended(), | |
| 1948 sanitization_info); | |
| 1949 #else | |
| 1970 EnableCrashDumping(GetCrashReporterClient()->IsRunningUnattended()); | 1950 EnableCrashDumping(GetCrashReporterClient()->IsRunningUnattended()); |
| 1951 #endif // defined(OS_ANDROID) | |
| 1971 } else if (GetCrashReporterClient()->EnableBreakpadForProcess(process_type)) { | 1952 } else if (GetCrashReporterClient()->EnableBreakpadForProcess(process_type)) { |
| 1972 #if defined(OS_ANDROID) | 1953 #if defined(OS_ANDROID) |
| 1973 NOTREACHED() << "Breakpad initialized with InitCrashReporter() instead of " | 1954 NOTREACHED() << "Breakpad initialized with InitCrashReporter() instead of " |
| 1974 "InitNonBrowserCrashReporter in " << process_type << " process."; | 1955 "InitNonBrowserCrashReporter in " << process_type << " process."; |
| 1975 return; | 1956 return; |
| 1976 #else | 1957 #else |
| 1977 // We might be chrooted in a zygote or renderer process so we cannot call | 1958 // We might be chrooted in a zygote or renderer process so we cannot call |
| 1978 // GetCollectStatsConsent because that needs access the the user's home | 1959 // GetCollectStatsConsent because that needs access the the user's home |
| 1979 // dir. Instead, we set a command line flag for these processes. | 1960 // dir. Instead, we set a command line flag for these processes. |
| 1980 // Even though plugins are not chrooted, we share the same code path for | 1961 // Even though plugins are not chrooted, we share the same code path for |
| 1981 // simplicity. | 1962 // simplicity. |
| 1982 if (!parsed_command_line.HasSwitch(switches::kEnableCrashReporter)) | 1963 if (!parsed_command_line.HasSwitch(switches::kEnableCrashReporter)) |
| 1983 return; | 1964 return; |
| 1984 | 1965 |
| 1985 InitCrashKeys(); | 1966 InitCrashKeys(); |
| 1986 SetChannelFromCommandLine(parsed_command_line); | 1967 SetChannelFromCommandLine(parsed_command_line); |
| 1987 SetClientIdFromCommandLine(parsed_command_line); | 1968 SetClientIdFromCommandLine(parsed_command_line); |
| 1988 EnableNonBrowserCrashDumping(); | 1969 EnableNonBrowserCrashDumping(); |
| 1989 VLOG(1) << "Non Browser crash dumping enabled for: " << process_type; | 1970 VLOG(1) << "Non Browser crash dumping enabled for: " << process_type; |
| 1990 #endif // #if defined(OS_ANDROID) | 1971 #endif // #if defined(OS_ANDROID) |
| 1991 } | 1972 } |
| 1992 | 1973 |
| 1993 PostEnableBreakpadInitialization(); | 1974 PostEnableBreakpadInitialization(); |
| 1994 } | 1975 } |
| 1995 | 1976 |
| 1996 #if defined(OS_ANDROID) | 1977 #if defined(OS_ANDROID) |
| 1997 void InitNonBrowserCrashReporterForAndroid(const std::string& process_type) { | 1978 void InitNonBrowserCrashReporterForAndroid(const std::string& process_type) { |
| 1979 SanitizationInfo sanitization_info; | |
| 1980 sanitization_info.should_sanitize_dumps = false; | |
| 1981 sanitization_info.skip_dump_if_principal_mapping_not_referenced = false; | |
| 1982 InitNonBrowserCrashReporterForAndroid(process_type, sanitization_info); | |
| 1983 } | |
| 1984 | |
| 1985 void InitNonBrowserCrashReporterForAndroid( | |
| 1986 const std::string& process_type, | |
| 1987 const SanitizationInfo& sanitization_info) { | |
| 1998 const base::CommandLine* command_line = | 1988 const base::CommandLine* command_line = |
| 1999 base::CommandLine::ForCurrentProcess(); | 1989 base::CommandLine::ForCurrentProcess(); |
| 2000 | 1990 |
| 2001 // Handler registration is LIFO. Install the microdump handler first, such | 1991 // Handler registration is LIFO. Install the microdump handler first, such |
| 2002 // that if conventional minidump crash reporting is enabled below, it takes | 1992 // that if conventional minidump crash reporting is enabled below, it takes |
| 2003 // precedence (i.e. its handler is run first) over the microdump handler. | 1993 // precedence (i.e. its handler is run first) over the microdump handler. |
| 2004 InitMicrodumpCrashHandlerIfNecessary(process_type); | 1994 InitMicrodumpCrashHandlerIfNecessary(process_type, sanitization_info); |
| 2005 | 1995 |
| 2006 if (command_line->HasSwitch(switches::kEnableCrashReporter)) { | 1996 if (command_line->HasSwitch(switches::kEnableCrashReporter)) { |
| 2007 // On Android we need to provide a FD to the file where the minidump is | 1997 // On Android we need to provide a FD to the file where the minidump is |
| 2008 // generated as the renderer and browser run with different UIDs | 1998 // generated as the renderer and browser run with different UIDs |
| 2009 // (preventing the browser from inspecting the renderer process). | 1999 // (preventing the browser from inspecting the renderer process). |
| 2010 int minidump_fd = base::GlobalDescriptors::GetInstance()->MaybeGet( | 2000 int minidump_fd = base::GlobalDescriptors::GetInstance()->MaybeGet( |
| 2011 GetCrashReporterClient()->GetAndroidMinidumpDescriptor()); | 2001 GetCrashReporterClient()->GetAndroidMinidumpDescriptor()); |
| 2012 if (minidump_fd < 0) { | 2002 if (minidump_fd < 0) { |
| 2013 NOTREACHED() << "Could not find minidump FD, crash reporting disabled."; | 2003 NOTREACHED() << "Could not find minidump FD, crash reporting disabled."; |
| 2014 } else { | 2004 } else { |
| 2015 InitCrashKeys(); | 2005 InitCrashKeys(); |
| 2016 EnableNonBrowserCrashDumping(process_type, minidump_fd); | 2006 EnableNonBrowserCrashDumping(process_type, minidump_fd, |
| 2007 sanitization_info); | |
| 2017 // Note: not installing DumpWithoutCrash handler here because browser | 2008 // Note: not installing DumpWithoutCrash handler here because browser |
| 2018 // is not set up to receive multiple reports from child process. | 2009 // is not set up to receive multiple reports from child process. |
| 2019 } | 2010 } |
| 2020 } | 2011 } |
| 2021 } | 2012 } |
| 2022 | 2013 |
| 2023 // The microdump handler does NOT upload anything. It just dumps out on the | 2014 // The microdump handler does NOT upload anything. It just dumps out on the |
| 2024 // system console (logcat) a restricted and serialized variant of a minidump. | 2015 // system console (logcat) a restricted and serialized variant of a minidump. |
| 2025 // See crbug.com/410294 for more details. | 2016 // See crbug.com/410294 for more details. |
| 2026 void InitMicrodumpCrashHandlerIfNecessary(const std::string& process_type) { | 2017 void InitMicrodumpCrashHandlerIfNecessary( |
| 2018 const std::string& process_type, | |
| 2019 const SanitizationInfo& sanitization_info) { | |
| 2027 if (!GetCrashReporterClient()->ShouldEnableBreakpadMicrodumps()) | 2020 if (!GetCrashReporterClient()->ShouldEnableBreakpadMicrodumps()) |
| 2028 return; | 2021 return; |
| 2029 | 2022 |
| 2030 VLOG(1) << "Enabling microdumps crash handler (process_type:" | 2023 VLOG(1) << "Enabling microdumps crash handler (process_type:" |
| 2031 << process_type << ")"; | 2024 << process_type << ")"; |
| 2032 | 2025 |
| 2033 // The exception handler runs in a compromised context and cannot use c_str() | 2026 // The exception handler runs in a compromised context and cannot use c_str() |
| 2034 // as that would require the heap. Therefore, we have to guarantee that the | 2027 // as that would require the heap. Therefore, we have to guarantee that the |
| 2035 // build fingerprint and product info pointers are always valid. | 2028 // build fingerprint and product info pointers are always valid. |
| 2036 const char* product_name = nullptr; | 2029 const char* product_name = nullptr; |
| 2037 const char* product_version = nullptr; | 2030 const char* product_version = nullptr; |
| 2038 GetCrashReporterClient()->GetProductNameAndVersion(&product_name, | 2031 GetCrashReporterClient()->GetProductNameAndVersion(&product_name, |
| 2039 &product_version); | 2032 &product_version); |
| 2040 | 2033 |
| 2041 const char* android_build_fp = | 2034 const char* android_build_fp = |
| 2042 base::android::BuildInfo::GetInstance()->android_build_fp(); | 2035 base::android::BuildInfo::GetInstance()->android_build_fp(); |
| 2043 | 2036 |
| 2044 g_microdump_info.Get().Initialize(process_type, product_name, product_version, | 2037 g_microdump_info.Get().Initialize(process_type, product_name, product_version, |
| 2045 android_build_fp); | 2038 android_build_fp, sanitization_info); |
| 2046 } | 2039 } |
| 2047 | 2040 |
| 2048 void AddGpuFingerprintToMicrodumpCrashHandler( | 2041 void AddGpuFingerprintToMicrodumpCrashHandler( |
| 2049 const std::string& gpu_fingerprint) { | 2042 const std::string& gpu_fingerprint) { |
| 2050 g_microdump_info.Get().SetGpuFingerprint(gpu_fingerprint); | 2043 g_microdump_info.Get().SetGpuFingerprintForMicrodump(gpu_fingerprint); |
| 2051 } | 2044 } |
| 2052 | 2045 |
| 2053 void GenerateMinidumpOnDemandForAndroid(int dump_fd) { | 2046 void GenerateMinidumpOnDemandForAndroid(int dump_fd) { |
| 2054 if (dump_fd >= 0) { | 2047 if (dump_fd >= 0) { |
| 2055 MinidumpDescriptor minidump_descriptor(dump_fd); | 2048 MinidumpDescriptor minidump_descriptor(dump_fd); |
| 2056 minidump_descriptor.set_size_limit(-1); | 2049 minidump_descriptor.set_size_limit(-1); |
| 2057 ExceptionHandler(minidump_descriptor, nullptr, MinidumpGenerated, nullptr, | 2050 ExceptionHandler(minidump_descriptor, nullptr, MinidumpGenerated, nullptr, |
| 2058 false, -1) | 2051 false, -1) |
| 2059 .WriteMinidump(); | 2052 .WriteMinidump(); |
| 2060 } | 2053 } |
| 2061 } | 2054 } |
| 2062 | 2055 |
| 2063 void SuppressDumpGeneration() { | 2056 void SuppressDumpGeneration() { |
| 2064 g_dumps_suppressed = G_DUMPS_SUPPRESSED_MAGIC; | 2057 g_dumps_suppressed = G_DUMPS_SUPPRESSED_MAGIC; |
| 2065 } | 2058 } |
| 2066 | |
| 2067 void SetSkipDumpIfPrincipalMappingNotReferenced( | |
| 2068 uintptr_t address_within_principal_mapping) { | |
| 2069 g_microdump_info.Get().SetSkipDumpIfPrincipalMappingNotReferenced( | |
| 2070 address_within_principal_mapping); | |
| 2071 } | |
| 2072 | |
| 2073 void SetShouldSanitizeDumps(bool should_sanitize_dumps) { | |
| 2074 g_microdump_info.Get().SetShouldSanitizeDumps(should_sanitize_dumps); | |
| 2075 } | |
| 2076 #endif // OS_ANDROID | 2059 #endif // OS_ANDROID |
| 2077 | 2060 |
| 2078 bool IsCrashReporterEnabled() { | 2061 bool IsCrashReporterEnabled() { |
| 2079 return g_is_crash_reporter_enabled; | 2062 return g_is_crash_reporter_enabled; |
| 2080 } | 2063 } |
| 2081 | 2064 |
| 2082 } // namespace breakpad | 2065 } // namespace breakpad |
| OLD | NEW |