Chromium Code Reviews| Index: components/crash/app/breakpad_linux.cc |
| diff --git a/components/crash/app/breakpad_linux.cc b/components/crash/app/breakpad_linux.cc |
| index 03ce34b1089d0baf441b940ed65a8212ee20b7d6..9130f63f685d573fa93251b23397c3cd85d4c087 100644 |
| --- a/components/crash/app/breakpad_linux.cc |
| +++ b/components/crash/app/breakpad_linux.cc |
| @@ -49,6 +49,7 @@ |
| #include "base/android/build_info.h" |
| #include "base/android/path_utils.h" |
| +#include "base/lazy_instance.h" |
| #endif |
| #include "third_party/lss/linux_syscall_support.h" |
| @@ -85,18 +86,29 @@ const char kUploadURL[] = "https://clients2.google.com/cr/report"; |
| bool g_is_crash_reporter_enabled = false; |
| uint64_t g_process_start_time = 0; |
| pid_t g_pid = 0; |
| -char* g_crash_log_path = NULL; |
| -ExceptionHandler* g_breakpad = NULL; |
| -ExceptionHandler* g_microdump = NULL; |
| +char* g_crash_log_path = nullptr; |
| +ExceptionHandler* g_breakpad = nullptr; |
| + |
| +#if defined(OS_ANDROID) |
| +ExceptionHandler* g_microdump = nullptr; |
| + |
| +base::LazyInstance<std::string>::Leaky g_microdump_build_fingerprint = |
| + LAZY_INSTANCE_INITIALIZER; |
| +const char* g_c_microdump_build_fingerprint = nullptr; |
| + |
| +base::LazyInstance<std::string>::Leaky g_microdump_product_info = |
| + LAZY_INSTANCE_INITIALIZER; |
| +const char* g_c_microdump_product_info = nullptr; |
| +#endif |
| #if defined(ADDRESS_SANITIZER) |
| -const char* g_asan_report_str = NULL; |
| +const char* g_asan_report_str = nullptr; |
| #endif |
| #if defined(OS_ANDROID) |
| -char* g_process_type = NULL; |
| +char* g_process_type = nullptr; |
| #endif |
| -CrashKeyStorage* g_crash_keys = NULL; |
| +CrashKeyStorage* g_crash_keys = nullptr; |
| // Writes the value |v| as 16 hex characters to the memory pointed at by |
| // |output|. |
| @@ -133,7 +145,7 @@ const size_t kUint64StringSize = 21; |
| void SetProcessStartTime() { |
| // Set the base process start time value. |
| struct timeval tv; |
| - if (!gettimeofday(&tv, NULL)) |
| + if (!gettimeofday(&tv, nullptr)) |
| g_process_start_time = timeval_to_ms(&tv); |
| else |
| g_process_start_time = 0; |
| @@ -512,9 +524,11 @@ void DumpProcess() { |
| if (g_breakpad) |
| g_breakpad->WriteMinidump(); |
| +#if defined(OS_ANDROID) |
| // If microdumps are enabled write also a microdump on the system log. |
| if (g_microdump) |
| g_microdump->WriteMinidump(); |
| +#endif |
| } |
| #if defined(OS_ANDROID) |
| @@ -678,9 +692,9 @@ void EnableCrashDumping(bool unattended) { |
| if (unattended) { |
| g_breakpad = new ExceptionHandler( |
| minidump_descriptor, |
| - NULL, |
| + nullptr, |
| CrashDoneNoUpload, |
| - NULL, |
| + nullptr, |
| true, // Install handlers. |
| -1); // Server file descriptor. -1 for in-process. |
| return; |
| @@ -690,9 +704,9 @@ void EnableCrashDumping(bool unattended) { |
| // Attended mode |
| g_breakpad = new ExceptionHandler( |
| minidump_descriptor, |
| - NULL, |
| + nullptr, |
| CrashDoneUpload, |
| - NULL, |
| + nullptr, |
| true, // Install handlers. |
| -1); // Server file descriptor. -1 for in-process. |
| #endif |
| @@ -710,7 +724,7 @@ bool MicrodumpCrashDone(const MinidumpDescriptor& minidump, |
| return false; |
| } |
| - const bool is_browser_process = (context != NULL); |
| + const bool is_browser_process = (context != nullptr); |
| return FinalizeCrashDoneAndroid(is_browser_process); |
| } |
| @@ -729,11 +743,30 @@ void InitMicrodumpCrashHandlerIfNecessary(const std::string& process_type) { |
| VLOG(1) << "Enabling microdumps crash handler (process_type:" |
| << process_type << ")"; |
| + |
| + const char* product_name = nullptr; |
| + const char* product_version = nullptr; |
| + GetCrashReporterClient()->GetProductNameAndVersion(&product_name, |
| + &product_version); |
| + g_microdump_product_info.Get() = product_name + string(":") + product_version; |
| + g_microdump_build_fingerprint.Get() = |
|
Lei Zhang
2015/05/15 10:37:18
or maybe get rid of the LazyInstance, and just do:
Primiano Tucci (use gerrit)
2015/05/15 11:41:44
Yeah, I guess it's easier to read if I leak string
|
| + base::android::BuildInfo::GetInstance()->android_build_fp(); |
| + |
| + // The exception handler runs in a compromised context and cannot use c_str() |
| + // as that would require the heap. Therefore, we have to guarantee that the |
| + // build fingerprint and product info pointers are always valid. |
| + g_c_microdump_product_info = g_microdump_product_info.Get().c_str(); |
| + g_c_microdump_build_fingerprint = g_microdump_build_fingerprint.Get().c_str(); |
| + |
| + MinidumpDescriptor descriptor(MinidumpDescriptor::kMicrodumpOnConsole); |
| + descriptor.SetMicrodumpProductInfo(g_c_microdump_product_info); |
| + descriptor.SetMicrodumpBuildFingerprint(g_c_microdump_build_fingerprint); |
| + |
| DCHECK(!g_microdump); |
| bool is_browser_process = process_type.empty() || process_type == "webview"; |
| g_microdump = new ExceptionHandler( |
| - MinidumpDescriptor(MinidumpDescriptor::kMicrodumpOnConsole), |
| - NULL, |
| + descriptor, |
| + nullptr, |
| MicrodumpCrashDone, |
| reinterpret_cast<void*>(is_browser_process), |
| true, // Install handlers. |
| @@ -755,11 +788,11 @@ bool CrashDoneInProcessNoUpload( |
| // Start constructing the message to send to the browser. |
| BreakpadInfo info = {0}; |
| - info.filename = NULL; |
| + info.filename = nullptr; |
| info.fd = descriptor.fd(); |
| info.process_type = g_process_type; |
| info.process_type_length = my_strlen(g_process_type); |
| - info.distro = NULL; |
| + info.distro = nullptr; |
| info.distro_length = 0; |
| info.upload = false; |
| info.process_start_time = g_process_start_time; |
| @@ -798,7 +831,7 @@ void EnableNonBrowserCrashDumping(const std::string& process_type, |
| g_process_type = new char[process_type_len]; |
| strncpy(g_process_type, process_type.c_str(), process_type_len); |
| new google_breakpad::ExceptionHandler(MinidumpDescriptor(minidump_fd), |
| - NULL, CrashDoneInProcessNoUpload, NULL, true, -1); |
| + nullptr, CrashDoneInProcessNoUpload, nullptr, true, -1); |
| } |
| #else |
| // Non-Browser = Extension, Gpu, Plugins, Ppapi and Renderer |
| @@ -902,9 +935,9 @@ void EnableNonBrowserCrashDumping() { |
| g_breakpad = new ExceptionHandler( |
| MinidumpDescriptor("/tmp"), // Unused but needed or Breakpad will assert. |
| - NULL, |
| - NULL, |
| - NULL, |
| + nullptr, |
| + nullptr, |
| + nullptr, |
| true, |
| -1); |
| g_breakpad->set_crash_generation_client(new NonBrowserCrashHandler()); |
| @@ -1057,7 +1090,7 @@ void ExecUploadProcessOrTerminate(const BreakpadInfo& info, |
| pid_flag, |
| uid_flag, |
| exe_flag, |
| - NULL, |
| + nullptr, |
| }; |
| static const char msg[] = "Cannot upload crash dump: cannot exec " |
| "/sbin/crash_reporter\n"; |
| @@ -1092,7 +1125,7 @@ void ExecUploadProcessOrTerminate(const BreakpadInfo& info, |
| "--tries=1", // Don't retry if the upload fails. |
| "-O", // output reply to fd 3 |
| "/dev/fd/3", |
| - NULL, |
| + nullptr, |
| }; |
| static const char msg[] = "Cannot upload crash dump: cannot exec " |
| "/usr/bin/wget\n"; |
| @@ -1137,7 +1170,7 @@ size_t WaitForCrashReportUploadProcess(int fd, size_t bytes_to_read, |
| return bytes_read; |
| } |
| -// |buf| should be |expected_len| + 1 characters in size and NULL terminated. |
| +// |buf| should be |expected_len| + 1 characters in size and nullptr terminated. |
| bool IsValidCrashReportId(const char* buf, size_t bytes_read, |
| size_t expected_len) { |
| if (bytes_read != expected_len) |
| @@ -1153,7 +1186,7 @@ bool IsValidCrashReportId(const char* buf, size_t bytes_read, |
| #endif |
| } |
| -// |buf| should be |expected_len| + 1 characters in size and NULL terminated. |
| +// |buf| should be |expected_len| + 1 characters in size and nullptr terminated. |
| void HandleCrashReportId(const char* buf, size_t bytes_read, |
| size_t expected_len) { |
| WriteNewline(); |
| @@ -1186,7 +1219,7 @@ void HandleCrashReportId(const char* buf, size_t bytes_read, |
| // Write crash dump id to crash log as: seconds_since_epoch,crash_id |
| struct kernel_timeval tv; |
| - if (g_crash_log_path && !sys_gettimeofday(&tv, NULL)) { |
| + if (g_crash_log_path && !sys_gettimeofday(&tv, nullptr)) { |
| uint64_t time = kernel_timeval_to_ms(&tv) / 1000; |
| char time_str[kUint64StringSize]; |
| const unsigned time_len = my_uint64_len(time); |
| @@ -1241,7 +1274,7 @@ void HandleCrashDump(const BreakpadInfo& info) { |
| size_t dump_size; |
| uint8_t* dump_data; |
| google_breakpad::PageAllocator allocator; |
| - const char* exe_buf = NULL; |
| + const char* exe_buf = nullptr; |
| if (GetCrashReporterClient()->HandleCrashDump(info.filename)) { |
| return; |
| @@ -1436,7 +1469,7 @@ void HandleCrashDump(const BreakpadInfo& info) { |
| writer.AddBoundary(); |
| writer.AddPairString(brand, android_build_info->brand()); |
| writer.AddBoundary(); |
| - if (android_build_info->java_exception_info() != NULL) { |
| + if (android_build_info->java_exception_info() != nullptr) { |
| writer.AddPairString(exception_info, |
| android_build_info->java_exception_info()); |
| writer.AddBoundary(); |
| @@ -1447,7 +1480,7 @@ void HandleCrashDump(const BreakpadInfo& info) { |
| if (info.process_start_time > 0) { |
| struct kernel_timeval tv; |
| - if (!sys_gettimeofday(&tv, NULL)) { |
| + if (!sys_gettimeofday(&tv, nullptr)) { |
| uint64_t time = kernel_timeval_to_ms(&tv); |
| if (time > info.process_start_time) { |
| time -= info.process_start_time; |
| @@ -1606,7 +1639,7 @@ void HandleCrashDump(const BreakpadInfo& info) { |
| WaitForCrashReportUploadProcess(fds[0], kCrashIdLength, id_buf); |
| HandleCrashReportId(id_buf, bytes_read, kCrashIdLength); |
| - if (sys_waitpid(upload_child, NULL, WNOHANG) == 0) { |
| + if (sys_waitpid(upload_child, nullptr, WNOHANG) == 0) { |
| // Upload process is still around, kill it. |
| sys_kill(upload_child, SIGKILL); |
| } |
| @@ -1625,7 +1658,7 @@ void HandleCrashDump(const BreakpadInfo& info) { |
| // Main browser process. |
| if (child <= 0) |
| return; |
| - (void) HANDLE_EINTR(sys_waitpid(child, NULL, 0)); |
| + (void) HANDLE_EINTR(sys_waitpid(child, nullptr, 0)); |
| } |
| void InitCrashReporter(const std::string& process_type) { |