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