| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 #include "components/browser_watcher/postmortem_report_collector.h" | 5 #include "components/browser_watcher/postmortem_report_collector.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/debug/activity_analyzer.h" | 9 #include "base/debug/activity_analyzer.h" |
| 10 #include "base/files/file_enumerator.h" | 10 #include "base/files/file_enumerator.h" |
| 11 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
| 14 #include "base/path_service.h" | 14 #include "base/path_service.h" |
| 15 #include "base/strings/string_piece.h" | 15 #include "base/strings/string_piece.h" |
| 16 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
| 17 #include "components/browser_watcher/postmortem_minidump_writer.h" | 17 #include "components/browser_watcher/postmortem_minidump_writer.h" |
| 18 #include "components/browser_watcher/stability_data_names.h" |
| 18 #include "third_party/crashpad/crashpad/client/settings.h" | 19 #include "third_party/crashpad/crashpad/client/settings.h" |
| 19 #include "third_party/crashpad/crashpad/util/misc/uuid.h" | 20 #include "third_party/crashpad/crashpad/util/misc/uuid.h" |
| 20 | 21 |
| 21 using base::FilePath; | 22 using base::FilePath; |
| 22 | 23 |
| 23 namespace browser_watcher { | 24 namespace browser_watcher { |
| 24 | 25 |
| 25 using ActivitySnapshot = base::debug::ThreadActivityAnalyzer::Snapshot; | 26 using ActivitySnapshot = base::debug::ThreadActivityAnalyzer::Snapshot; |
| 26 using base::debug::ActivityUserData; | 27 using base::debug::ActivityUserData; |
| 27 using base::debug::GlobalActivityAnalyzer; | 28 using base::debug::GlobalActivityAnalyzer; |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 CrashReportDatabase::OperationStatus database_status = | 218 CrashReportDatabase::OperationStatus database_status = |
| 218 report_database->PrepareNewCrashReport(&new_report); | 219 report_database->PrepareNewCrashReport(&new_report); |
| 219 if (database_status != CrashReportDatabase::kNoError) { | 220 if (database_status != CrashReportDatabase::kNoError) { |
| 220 LOG(ERROR) << "PrepareNewCrashReport failed"; | 221 LOG(ERROR) << "PrepareNewCrashReport failed"; |
| 221 return PREPARE_NEW_CRASH_REPORT_FAILED; | 222 return PREPARE_NEW_CRASH_REPORT_FAILED; |
| 222 } | 223 } |
| 223 CrashReportDatabase::CallErrorWritingCrashReport | 224 CrashReportDatabase::CallErrorWritingCrashReport |
| 224 call_error_writing_crash_report(report_database, new_report); | 225 call_error_writing_crash_report(report_database, new_report); |
| 225 | 226 |
| 226 // Write the report to a minidump. | 227 // Write the report to a minidump. |
| 227 if (!WriteReportToMinidump(*report_proto, client_id, new_report->uuid, | 228 if (!WriteReportToMinidump(report_proto.get(), client_id, new_report->uuid, |
| 228 reinterpret_cast<FILE*>(new_report->handle))) { | 229 reinterpret_cast<FILE*>(new_report->handle))) { |
| 229 return WRITE_TO_MINIDUMP_FAILED; | 230 return WRITE_TO_MINIDUMP_FAILED; |
| 230 } | 231 } |
| 231 | 232 |
| 232 // If the file cannot be deleted, do not report its contents. Note this can | 233 // If the file cannot be deleted, do not report its contents. Note this can |
| 233 // lead to under reporting and retries. However, under reporting is | 234 // lead to under reporting and retries. However, under reporting is |
| 234 // preferable to the over reporting that would happen with a file that | 235 // preferable to the over reporting that would happen with a file that |
| 235 // cannot be deleted. | 236 // cannot be deleted. |
| 236 // TODO(manzagop): metrics for the number of non-deletable files. | 237 // TODO(manzagop): metrics for the number of non-deletable files. |
| 237 if (!base::DeleteFile(file, false)) { | 238 if (!base::DeleteFile(file, false)) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 | 279 |
| 279 // Create the report, then flesh it out. | 280 // Create the report, then flesh it out. |
| 280 report->reset(new StabilityReport()); | 281 report->reset(new StabilityReport()); |
| 281 | 282 |
| 282 // Collect log messages. | 283 // Collect log messages. |
| 283 for (const std::string& message : log_messages) { | 284 for (const std::string& message : log_messages) { |
| 284 (*report)->add_log_messages(message); | 285 (*report)->add_log_messages(message); |
| 285 } | 286 } |
| 286 | 287 |
| 287 // Collect global user data. | 288 // Collect global user data. |
| 288 CollectUserData(global_data_snapshot, (*report)->mutable_global_data()); | 289 google::protobuf::Map<std::string, TypedValue>& global_data = |
| 290 *(*report)->mutable_global_data(); |
| 291 CollectUserData(global_data_snapshot, &global_data); |
| 292 |
| 293 // Add the reporting Chrome's details to the report. |
| 294 global_data[kStabilityReporterChannel].set_string_value(channel_name()); |
| 295 #if defined(ARCH_CPU_X86) |
| 296 global_data[kStabilityReporterPlatform].set_string_value( |
| 297 std::string("Win32")); |
| 298 #elif defined(ARCH_CPU_X86_64) |
| 299 global_data[kStabilityReporterPlatform].set_string_value( |
| 300 std::string("Win64")); |
| 301 #endif |
| 302 global_data[kStabilityReporterProduct].set_string_value(product_name()); |
| 303 global_data[kStabilityReporterVersion].set_string_value(version_number()); |
| 289 | 304 |
| 290 // Collect thread activity data. | 305 // Collect thread activity data. |
| 291 // Note: a single process is instrumented. | 306 // Note: a single process is instrumented. |
| 292 ProcessState* process_state = (*report)->add_process_states(); | 307 ProcessState* process_state = (*report)->add_process_states(); |
| 293 for (; thread_analyzer != nullptr; | 308 for (; thread_analyzer != nullptr; |
| 294 thread_analyzer = global_analyzer->GetNextAnalyzer()) { | 309 thread_analyzer = global_analyzer->GetNextAnalyzer()) { |
| 295 // Only valid analyzers are expected per contract of GetFirstAnalyzer / | 310 // Only valid analyzers are expected per contract of GetFirstAnalyzer / |
| 296 // GetNextAnalyzer. | 311 // GetNextAnalyzer. |
| 297 DCHECK(thread_analyzer->IsValid()); | 312 DCHECK(thread_analyzer->IsValid()); |
| 298 | 313 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 | 370 |
| 356 // Collect user data | 371 // Collect user data |
| 357 if (i < snapshot.user_data_stack.size()) { | 372 if (i < snapshot.user_data_stack.size()) { |
| 358 CollectUserData(snapshot.user_data_stack[i], | 373 CollectUserData(snapshot.user_data_stack[i], |
| 359 collected->mutable_user_data()); | 374 collected->mutable_user_data()); |
| 360 } | 375 } |
| 361 } | 376 } |
| 362 } | 377 } |
| 363 | 378 |
| 364 bool PostmortemReportCollector::WriteReportToMinidump( | 379 bool PostmortemReportCollector::WriteReportToMinidump( |
| 365 const StabilityReport& report, | 380 StabilityReport* report, |
| 366 const crashpad::UUID& client_id, | 381 const crashpad::UUID& client_id, |
| 367 const crashpad::UUID& report_id, | 382 const crashpad::UUID& report_id, |
| 368 base::PlatformFile minidump_file) { | 383 base::PlatformFile minidump_file) { |
| 369 MinidumpInfo minidump_info; | 384 DCHECK(report); |
| 370 minidump_info.client_id = client_id; | |
| 371 minidump_info.report_id = report_id; | |
| 372 // TODO(manzagop): replace this information, i.e. the reporter's attributes, | |
| 373 // by that of the reportee. Doing so requires adding this information to the | |
| 374 // stability report. In the meantime, there is a tolerable information | |
| 375 // mismatch after upgrades. | |
| 376 minidump_info.product_name = product_name(); | |
| 377 minidump_info.version_number = version_number(); | |
| 378 minidump_info.channel_name = channel_name(); | |
| 379 #if defined(ARCH_CPU_X86) | |
| 380 minidump_info.platform = std::string("Win32"); | |
| 381 #elif defined(ARCH_CPU_X86_64) | |
| 382 minidump_info.platform = std::string("Win64"); | |
| 383 #endif | |
| 384 | 385 |
| 385 return WritePostmortemDump(minidump_file, report, minidump_info); | 386 return WritePostmortemDump(minidump_file, client_id, report_id, report); |
| 386 } | 387 } |
| 387 | 388 |
| 388 } // namespace browser_watcher | 389 } // namespace browser_watcher |
| OLD | NEW |