Chromium Code Reviews| 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 "base/debug/activity_analyzer.h" | 5 #include "base/debug/activity_analyzer.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | |
| 8 | 9 |
| 9 #include "base/files/file.h" | 10 #include "base/files/file.h" |
| 10 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
| 11 #include "base/files/memory_mapped_file.h" | 12 #include "base/files/memory_mapped_file.h" |
| 12 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
| 13 #include "base/logging.h" | 14 #include "base/logging.h" |
| 14 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
| 16 #include "base/metrics/histogram_macros.h" | |
| 15 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
| 16 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
| 17 | 19 |
| 18 namespace base { | 20 namespace base { |
| 19 namespace debug { | 21 namespace debug { |
| 20 | 22 |
| 21 namespace { | 23 namespace { |
| 22 // An empty snapshot that can be returned when there otherwise is none. | 24 // An empty snapshot that can be returned when there otherwise is none. |
| 23 LazyInstance<ActivityUserData::Snapshot>::Leaky g_empty_user_data_snapshot; | 25 LazyInstance<ActivityUserData::Snapshot>::Leaky g_empty_user_data_snapshot; |
| 26 | |
| 27 #if !defined(OS_NACL) | |
| 28 // DO NOT CHANGE VALUES. This is logged persistently in a histogram. | |
| 29 enum AnalyzerCreationError { | |
| 30 kInvalidMemoryMappedFile = 0, | |
|
bcwhite
2017/04/19 18:54:07
It's standard practice not to specify the numerica
manzagop (departed)
2017/04/19 19:26:57
Done.
| |
| 31 kPmaBadFile = 1, | |
| 32 kPmaUninitialized = 2, | |
| 33 kPmaDeleted = 3, | |
| 34 kPmaCorrupt = 4, | |
| 35 kAnalyzerCreationErrorMax = 5 | |
| 36 }; | |
| 37 | |
| 38 void LogAnalyzerCreationError(AnalyzerCreationError error) { | |
| 39 UMA_HISTOGRAM_ENUMERATION("ActivityTracker.Collect.AnalyzerCreationError", | |
| 40 error, kAnalyzerCreationErrorMax); | |
| 41 } | |
| 42 #endif // !defined(OS_NACL) | |
| 43 | |
| 24 } // namespace | 44 } // namespace |
| 25 | 45 |
| 26 ThreadActivityAnalyzer::Snapshot::Snapshot() {} | 46 ThreadActivityAnalyzer::Snapshot::Snapshot() {} |
| 27 ThreadActivityAnalyzer::Snapshot::~Snapshot() {} | 47 ThreadActivityAnalyzer::Snapshot::~Snapshot() {} |
| 28 | 48 |
| 29 ThreadActivityAnalyzer::ThreadActivityAnalyzer( | 49 ThreadActivityAnalyzer::ThreadActivityAnalyzer( |
| 30 const ThreadActivityTracker& tracker) | 50 const ThreadActivityTracker& tracker) |
| 31 : activity_snapshot_valid_(tracker.CreateSnapshot(&activity_snapshot_)) {} | 51 : activity_snapshot_valid_(tracker.CreateSnapshot(&activity_snapshot_)) {} |
| 32 | 52 |
| 33 ThreadActivityAnalyzer::ThreadActivityAnalyzer(void* base, size_t size) | 53 ThreadActivityAnalyzer::ThreadActivityAnalyzer(void* base, size_t size) |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 56 // The global GetUserDataSnapshot will return an empty snapshot if the ref | 76 // The global GetUserDataSnapshot will return an empty snapshot if the ref |
| 57 // or id is not valid. | 77 // or id is not valid. |
| 58 activity_snapshot_.user_data_stack.push_back(global->GetUserDataSnapshot( | 78 activity_snapshot_.user_data_stack.push_back(global->GetUserDataSnapshot( |
| 59 activity_snapshot_.process_id, activity.user_data_ref, | 79 activity_snapshot_.process_id, activity.user_data_ref, |
| 60 activity.user_data_id)); | 80 activity.user_data_id)); |
| 61 } | 81 } |
| 62 } | 82 } |
| 63 | 83 |
| 64 GlobalActivityAnalyzer::GlobalActivityAnalyzer( | 84 GlobalActivityAnalyzer::GlobalActivityAnalyzer( |
| 65 std::unique_ptr<PersistentMemoryAllocator> allocator) | 85 std::unique_ptr<PersistentMemoryAllocator> allocator) |
| 66 : allocator_(std::move(allocator)), allocator_iterator_(allocator_.get()) {} | 86 : allocator_(std::move(allocator)), allocator_iterator_(allocator_.get()) { |
| 87 DCHECK(allocator_); | |
| 88 } | |
| 67 | 89 |
| 68 GlobalActivityAnalyzer::~GlobalActivityAnalyzer() {} | 90 GlobalActivityAnalyzer::~GlobalActivityAnalyzer() {} |
| 69 | 91 |
| 70 #if !defined(OS_NACL) | 92 #if !defined(OS_NACL) |
| 71 // static | 93 // static |
| 72 std::unique_ptr<GlobalActivityAnalyzer> GlobalActivityAnalyzer::CreateWithFile( | 94 std::unique_ptr<GlobalActivityAnalyzer> GlobalActivityAnalyzer::CreateWithFile( |
| 73 const FilePath& file_path) { | 95 const FilePath& file_path) { |
| 74 // Map the file read-write so it can guarantee consistency between | 96 // Map the file read-write so it can guarantee consistency between |
| 75 // the analyzer and any trackers that my still be active. | 97 // the analyzer and any trackers that my still be active. |
| 76 std::unique_ptr<MemoryMappedFile> mmfile(new MemoryMappedFile()); | 98 std::unique_ptr<MemoryMappedFile> mmfile(new MemoryMappedFile()); |
| 77 mmfile->Initialize(file_path, MemoryMappedFile::READ_WRITE); | 99 mmfile->Initialize(file_path, MemoryMappedFile::READ_WRITE); |
| 78 if (!mmfile->IsValid()) | 100 if (!mmfile->IsValid()) { |
| 101 LogAnalyzerCreationError(kInvalidMemoryMappedFile); | |
| 79 return nullptr; | 102 return nullptr; |
| 103 } | |
| 80 | 104 |
| 81 if (!FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile, true)) | 105 if (!FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile, true)) { |
| 106 LogAnalyzerCreationError(kPmaBadFile); | |
| 82 return nullptr; | 107 return nullptr; |
| 108 } | |
| 83 | 109 |
| 84 return WrapUnique( | 110 std::unique_ptr<FilePersistentMemoryAllocator> allocator( |
| 85 new GlobalActivityAnalyzer(MakeUnique<FilePersistentMemoryAllocator>( | 111 new FilePersistentMemoryAllocator(std::move(mmfile), 0, 0, |
| 86 std::move(mmfile), 0, 0, base::StringPiece(), true))); | 112 base::StringPiece(), true)); |
| 113 if (allocator->GetMemoryState() == | |
| 114 PersistentMemoryAllocator::MEMORY_UNINITIALIZED) { | |
| 115 LogAnalyzerCreationError(kPmaUninitialized); | |
| 116 return nullptr; | |
| 117 } | |
| 118 if (allocator->GetMemoryState() == | |
| 119 PersistentMemoryAllocator::MEMORY_DELETED) { | |
| 120 LogAnalyzerCreationError(kPmaDeleted); | |
| 121 return nullptr; | |
| 122 } | |
| 123 if (allocator->IsCorrupt()) { | |
| 124 LogAnalyzerCreationError(kPmaCorrupt); | |
| 125 return nullptr; | |
| 126 } | |
| 127 | |
| 128 return WrapUnique(new GlobalActivityAnalyzer(std::move(allocator))); | |
| 87 } | 129 } |
| 88 #endif // !defined(OS_NACL) | 130 #endif // !defined(OS_NACL) |
| 89 | 131 |
| 90 int64_t GlobalActivityAnalyzer::GetFirstProcess() { | 132 int64_t GlobalActivityAnalyzer::GetFirstProcess() { |
| 91 PrepareAllAnalyzers(); | 133 PrepareAllAnalyzers(); |
| 92 return GetNextProcess(); | 134 return GetNextProcess(); |
| 93 } | 135 } |
| 94 | 136 |
| 95 int64_t GlobalActivityAnalyzer::GetNextProcess() { | 137 int64_t GlobalActivityAnalyzer::GetNextProcess() { |
| 96 if (process_ids_.empty()) | 138 if (process_ids_.empty()) |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 208 | 250 |
| 209 return modules; | 251 return modules; |
| 210 } | 252 } |
| 211 | 253 |
| 212 GlobalActivityAnalyzer::ProgramLocation | 254 GlobalActivityAnalyzer::ProgramLocation |
| 213 GlobalActivityAnalyzer::GetProgramLocationFromAddress(uint64_t address) { | 255 GlobalActivityAnalyzer::GetProgramLocationFromAddress(uint64_t address) { |
| 214 // TODO(bcwhite): Implement this. | 256 // TODO(bcwhite): Implement this. |
| 215 return { 0, 0 }; | 257 return { 0, 0 }; |
| 216 } | 258 } |
| 217 | 259 |
| 260 bool GlobalActivityAnalyzer::IsDataComplete() const { | |
| 261 DCHECK(allocator_); | |
| 262 return !allocator_->IsFull(); | |
| 263 } | |
| 264 | |
| 218 GlobalActivityAnalyzer::UserDataSnapshot::UserDataSnapshot() {} | 265 GlobalActivityAnalyzer::UserDataSnapshot::UserDataSnapshot() {} |
| 219 GlobalActivityAnalyzer::UserDataSnapshot::UserDataSnapshot( | 266 GlobalActivityAnalyzer::UserDataSnapshot::UserDataSnapshot( |
| 220 const UserDataSnapshot& rhs) = default; | 267 const UserDataSnapshot& rhs) = default; |
| 221 GlobalActivityAnalyzer::UserDataSnapshot::UserDataSnapshot( | 268 GlobalActivityAnalyzer::UserDataSnapshot::UserDataSnapshot( |
| 222 UserDataSnapshot&& rhs) = default; | 269 UserDataSnapshot&& rhs) = default; |
| 223 GlobalActivityAnalyzer::UserDataSnapshot::~UserDataSnapshot() {} | 270 GlobalActivityAnalyzer::UserDataSnapshot::~UserDataSnapshot() {} |
| 224 | 271 |
| 225 void GlobalActivityAnalyzer::PrepareAllAnalyzers() { | 272 void GlobalActivityAnalyzer::PrepareAllAnalyzers() { |
| 226 // Record the time when analysis started. | 273 // Record the time when analysis started. |
| 227 analysis_stamp_ = base::Time::Now().ToInternalValue(); | 274 analysis_stamp_ = base::Time::Now().ToInternalValue(); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 320 } break; | 367 } break; |
| 321 } | 368 } |
| 322 } | 369 } |
| 323 | 370 |
| 324 // Reverse the list of PIDs so that they get popped in the order found. | 371 // Reverse the list of PIDs so that they get popped in the order found. |
| 325 std::reverse(process_ids_.begin(), process_ids_.end()); | 372 std::reverse(process_ids_.begin(), process_ids_.end()); |
| 326 } | 373 } |
| 327 | 374 |
| 328 } // namespace debug | 375 } // namespace debug |
| 329 } // namespace base | 376 } // namespace base |
| OLD | NEW |