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