| 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 "third_party/crashpad/crashpad/client/settings.h" | 18 #include "third_party/crashpad/crashpad/client/settings.h" |
| 19 #include "third_party/crashpad/crashpad/util/misc/uuid.h" | 19 #include "third_party/crashpad/crashpad/util/misc/uuid.h" |
| 20 | 20 |
| 21 using base::FilePath; | 21 using base::FilePath; |
| 22 | 22 |
| 23 namespace browser_watcher { | 23 namespace browser_watcher { |
| 24 | 24 |
| 25 using ActivitySnapshot = base::debug::ThreadActivityAnalyzer::Snapshot; | 25 using ActivitySnapshot = base::debug::ThreadActivityAnalyzer::Snapshot; |
| 26 using base::debug::ActivityUserData; | 26 using base::debug::ActivityUserData; |
| 27 using base::debug::GlobalActivityAnalyzer; | 27 using base::debug::GlobalActivityAnalyzer; |
| 28 using base::debug::GlobalActivityTracker; |
| 28 using base::debug::ThreadActivityAnalyzer; | 29 using base::debug::ThreadActivityAnalyzer; |
| 29 using crashpad::CrashReportDatabase; | 30 using crashpad::CrashReportDatabase; |
| 30 | 31 |
| 31 namespace { | 32 namespace { |
| 32 | 33 |
| 33 // Collects stability user data from the recorded format to the collected | 34 // Collects stability user data from the recorded format to the collected |
| 34 // format. | 35 // format. |
| 35 void CollectUserData( | 36 void CollectUserData( |
| 36 const ActivityUserData::Snapshot& recorded_map, | 37 const ActivityUserData::Snapshot& recorded_map, |
| 37 google::protobuf::Map<std::string, TypedValue>* collected_map) { | 38 google::protobuf::Map<std::string, TypedValue>* collected_map) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 break; | 83 break; |
| 83 case ActivityUserData::UNSIGNED_VALUE: | 84 case ActivityUserData::UNSIGNED_VALUE: |
| 84 collected_value.set_unsigned_value(recorded_value.GetUint()); | 85 collected_value.set_unsigned_value(recorded_value.GetUint()); |
| 85 break; | 86 break; |
| 86 } | 87 } |
| 87 | 88 |
| 88 (*collected_map)[name_and_value.first].Swap(&collected_value); | 89 (*collected_map)[name_and_value.first].Swap(&collected_value); |
| 89 } | 90 } |
| 90 } | 91 } |
| 91 | 92 |
| 93 void CollectModuleInformation( |
| 94 const std::vector<GlobalActivityTracker::ModuleInfo>& modules, |
| 95 ProcessState* process_state) { |
| 96 DCHECK(process_state); |
| 97 |
| 98 char code_identifier[17]; |
| 99 char debug_identifier[41]; |
| 100 |
| 101 for (const GlobalActivityTracker::ModuleInfo& recorded : modules) { |
| 102 CodeModule* collected = process_state->add_modules(); |
| 103 collected->set_base_address(recorded.address); |
| 104 collected->set_size(recorded.size); |
| 105 collected->set_code_file(recorded.file); |
| 106 |
| 107 // Compute the code identifier using the required format. |
| 108 snprintf(code_identifier, sizeof(code_identifier), "%08X%zx", |
| 109 recorded.timestamp, recorded.size); |
| 110 collected->set_code_identifier(code_identifier); |
| 111 collected->set_debug_file(recorded.debug_file); |
| 112 |
| 113 // Compute the debug identifier using the required format. |
| 114 const crashpad::UUID* uuid = |
| 115 reinterpret_cast<const crashpad::UUID*>(recorded.identifier); |
| 116 snprintf(debug_identifier, sizeof(debug_identifier), |
| 117 "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%x", uuid->data_1, |
| 118 uuid->data_2, uuid->data_3, uuid->data_4[0], uuid->data_4[1], |
| 119 uuid->data_5[0], uuid->data_5[1], uuid->data_5[2], uuid->data_5[3], |
| 120 uuid->data_5[4], uuid->data_5[5], recorded.age); |
| 121 collected->set_debug_identifier(debug_identifier); |
| 122 collected->set_is_unloaded(!recorded.is_loaded); |
| 123 } |
| 124 } |
| 125 |
| 92 } // namespace | 126 } // namespace |
| 93 | 127 |
| 94 PostmortemReportCollector::PostmortemReportCollector( | 128 PostmortemReportCollector::PostmortemReportCollector( |
| 95 const std::string& product_name, | 129 const std::string& product_name, |
| 96 const std::string& version_number, | 130 const std::string& version_number, |
| 97 const std::string& channel_name) | 131 const std::string& channel_name) |
| 98 : product_name_(product_name), | 132 : product_name_(product_name), |
| 99 version_number_(version_number), | 133 version_number_(version_number), |
| 100 channel_name_(channel_name) {} | 134 channel_name_(channel_name) {} |
| 101 | 135 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 process_state->set_process_id( | 300 process_state->set_process_id( |
| 267 thread_analyzer->activity_snapshot().process_id); | 301 thread_analyzer->activity_snapshot().process_id); |
| 268 } | 302 } |
| 269 DCHECK_EQ(thread_analyzer->activity_snapshot().process_id, | 303 DCHECK_EQ(thread_analyzer->activity_snapshot().process_id, |
| 270 process_state->process_id()); | 304 process_state->process_id()); |
| 271 | 305 |
| 272 ThreadState* thread_state = process_state->add_threads(); | 306 ThreadState* thread_state = process_state->add_threads(); |
| 273 CollectThread(thread_analyzer->activity_snapshot(), thread_state); | 307 CollectThread(thread_analyzer->activity_snapshot(), thread_state); |
| 274 } | 308 } |
| 275 | 309 |
| 310 // Collect module information. |
| 311 CollectModuleInformation(global_analyzer->GetModules(), process_state); |
| 312 |
| 276 return SUCCESS; | 313 return SUCCESS; |
| 277 } | 314 } |
| 278 | 315 |
| 279 void PostmortemReportCollector::CollectThread( | 316 void PostmortemReportCollector::CollectThread( |
| 280 const base::debug::ThreadActivityAnalyzer::Snapshot& snapshot, | 317 const base::debug::ThreadActivityAnalyzer::Snapshot& snapshot, |
| 281 ThreadState* thread_state) { | 318 ThreadState* thread_state) { |
| 282 DCHECK(thread_state); | 319 DCHECK(thread_state); |
| 283 | 320 |
| 284 thread_state->set_thread_name(snapshot.thread_name); | 321 thread_state->set_thread_name(snapshot.thread_name); |
| 285 thread_state->set_thread_id(snapshot.thread_id); | 322 thread_state->set_thread_id(snapshot.thread_id); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 #if defined(ARCH_CPU_X86) | 379 #if defined(ARCH_CPU_X86) |
| 343 minidump_info.platform = std::string("Win32"); | 380 minidump_info.platform = std::string("Win32"); |
| 344 #elif defined(ARCH_CPU_X86_64) | 381 #elif defined(ARCH_CPU_X86_64) |
| 345 minidump_info.platform = std::string("Win64"); | 382 minidump_info.platform = std::string("Win64"); |
| 346 #endif | 383 #endif |
| 347 | 384 |
| 348 return WritePostmortemDump(minidump_file, report, minidump_info); | 385 return WritePostmortemDump(minidump_file, report, minidump_info); |
| 349 } | 386 } |
| 350 | 387 |
| 351 } // namespace browser_watcher | 388 } // namespace browser_watcher |
| OLD | NEW |