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 "base/files/file.h" | 7 #include "base/files/file.h" |
| 8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
| 9 #include "base/files/memory_mapped_file.h" | 9 #include "base/files/memory_mapped_file.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
| 13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 14 | 14 |
| 15 namespace base { | 15 namespace base { |
| 16 namespace debug { | 16 namespace debug { |
| 17 | 17 |
| 18 ThreadActivityAnalyzer::Snapshot::Snapshot() {} | |
| 19 ThreadActivityAnalyzer::Snapshot::~Snapshot() {} | |
| 20 | |
| 18 ThreadActivityAnalyzer::ThreadActivityAnalyzer( | 21 ThreadActivityAnalyzer::ThreadActivityAnalyzer( |
| 19 const ThreadActivityTracker& tracker) | 22 const ThreadActivityTracker& tracker) |
| 20 : activity_snapshot_valid_(tracker.Snapshot(&activity_snapshot_)) {} | 23 : activity_snapshot_valid_(tracker.CreateSnapshot(&activity_snapshot_)) {} |
| 21 | 24 |
| 22 ThreadActivityAnalyzer::ThreadActivityAnalyzer(void* base, size_t size) | 25 ThreadActivityAnalyzer::ThreadActivityAnalyzer(void* base, size_t size) |
| 23 : ThreadActivityAnalyzer(ThreadActivityTracker(base, size)) {} | 26 : ThreadActivityAnalyzer(ThreadActivityTracker(base, size)) {} |
| 24 | 27 |
| 25 ThreadActivityAnalyzer::ThreadActivityAnalyzer( | 28 ThreadActivityAnalyzer::ThreadActivityAnalyzer( |
| 26 PersistentMemoryAllocator* allocator, | 29 PersistentMemoryAllocator* allocator, |
| 27 PersistentMemoryAllocator::Reference reference) | 30 PersistentMemoryAllocator::Reference reference) |
| 28 : ThreadActivityAnalyzer(allocator->GetAsArray<char>( | 31 : ThreadActivityAnalyzer(allocator->GetAsArray<char>( |
| 29 reference, | 32 reference, |
| 30 GlobalActivityTracker::kTypeIdActivityTracker, | 33 GlobalActivityTracker::kTypeIdActivityTracker, |
| 31 1), | 34 1), |
| 32 allocator->GetAllocSize(reference)) {} | 35 allocator->GetAllocSize(reference)) {} |
| 33 | 36 |
| 34 ThreadActivityAnalyzer::~ThreadActivityAnalyzer() {} | 37 ThreadActivityAnalyzer::~ThreadActivityAnalyzer() {} |
| 35 | 38 |
| 39 void ThreadActivityAnalyzer::AddGlobalInformation( | |
| 40 GlobalActivityAnalyzer* global) { | |
| 41 if (!IsValid()) | |
| 42 return; | |
| 43 | |
| 44 // User-data is held at the global scope even though it's referenced an the | |
|
manzagop (departed)
2016/12/02 22:13:33
typo: referenced an -> at
bcwhite
2016/12/08 21:30:56
Done.
| |
| 45 // thread scope. | |
| 46 activity_snapshot_.user_data_stack.clear(); | |
| 47 for (auto& activity : activity_snapshot_.activity_stack) { | |
| 48 // The global GetUserDataSnapshot will return an empty snapshot if the ref | |
| 49 // or id is not valid. | |
| 50 activity_snapshot_.user_data_stack.push_back(global->GetUserDataSnapshot( | |
| 51 activity.user_data_ref, activity.user_data_id)); | |
| 52 } | |
| 53 } | |
| 54 | |
| 36 GlobalActivityAnalyzer::GlobalActivityAnalyzer( | 55 GlobalActivityAnalyzer::GlobalActivityAnalyzer( |
| 37 std::unique_ptr<PersistentMemoryAllocator> allocator) | 56 std::unique_ptr<PersistentMemoryAllocator> allocator) |
| 38 : allocator_(std::move(allocator)), allocator_iterator_(allocator_.get()) {} | 57 : allocator_(std::move(allocator)), allocator_iterator_(allocator_.get()) {} |
| 39 | 58 |
| 40 GlobalActivityAnalyzer::~GlobalActivityAnalyzer() {} | 59 GlobalActivityAnalyzer::~GlobalActivityAnalyzer() {} |
| 41 | 60 |
| 42 #if !defined(OS_NACL) | 61 #if !defined(OS_NACL) |
| 43 // static | 62 // static |
| 44 std::unique_ptr<GlobalActivityAnalyzer> GlobalActivityAnalyzer::CreateWithFile( | 63 std::unique_ptr<GlobalActivityAnalyzer> GlobalActivityAnalyzer::CreateWithFile( |
| 45 const FilePath& file_path) { | 64 const FilePath& file_path) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 76 } | 95 } |
| 77 | 96 |
| 78 ThreadActivityAnalyzer* GlobalActivityAnalyzer::GetAnalyzerForThread( | 97 ThreadActivityAnalyzer* GlobalActivityAnalyzer::GetAnalyzerForThread( |
| 79 const ThreadKey& key) { | 98 const ThreadKey& key) { |
| 80 auto found = analyzers_.find(key); | 99 auto found = analyzers_.find(key); |
| 81 if (found == analyzers_.end()) | 100 if (found == analyzers_.end()) |
| 82 return nullptr; | 101 return nullptr; |
| 83 return found->second.get(); | 102 return found->second.get(); |
| 84 } | 103 } |
| 85 | 104 |
| 105 ActivityUserData::Snapshot GlobalActivityAnalyzer::GetUserDataSnapshot( | |
| 106 uint32_t ref, | |
| 107 uint32_t id) { | |
| 108 ActivityUserData::Snapshot snapshot; | |
| 109 | |
| 110 void* memory = allocator_->GetAsArray<char>( | |
| 111 ref, GlobalActivityTracker::kTypeIdUserDataRecord, | |
| 112 PersistentMemoryAllocator::kSizeAny); | |
| 113 if (memory) { | |
| 114 size_t size = allocator_->GetAllocSize(ref); | |
| 115 const ActivityUserData user_data(memory, size); | |
| 116 user_data.CreateSnapshot(&snapshot); | |
| 117 if (user_data.id() != id) { | |
| 118 // This allocation has been overwritten since it was created. Return an | |
| 119 // empty snapshot because whatever was captured is incorrect. | |
| 120 snapshot.clear(); | |
| 121 } | |
| 122 } | |
| 123 | |
| 124 return snapshot; | |
| 125 } | |
| 126 | |
| 127 ActivityUserData::Snapshot GlobalActivityAnalyzer::GetGlobalUserDataSnapshot() { | |
| 128 ActivityUserData::Snapshot snapshot; | |
| 129 | |
| 130 PersistentMemoryAllocator::Reference ref = | |
| 131 PersistentMemoryAllocator::Iterator(allocator_.get()) | |
| 132 .GetNextOfType(GlobalActivityTracker::kTypeIdGlobalDataRecord); | |
| 133 void* memory = allocator_->GetAsArray<char>( | |
| 134 ref, GlobalActivityTracker::kTypeIdGlobalDataRecord, | |
| 135 PersistentMemoryAllocator::kSizeAny); | |
| 136 if (memory) { | |
| 137 size_t size = allocator_->GetAllocSize(ref); | |
| 138 const ActivityUserData global_data(memory, size); | |
| 139 global_data.CreateSnapshot(&snapshot); | |
| 140 } | |
| 141 | |
| 142 return snapshot; | |
| 143 } | |
| 144 | |
| 86 GlobalActivityAnalyzer::ProgramLocation | 145 GlobalActivityAnalyzer::ProgramLocation |
| 87 GlobalActivityAnalyzer::GetProgramLocationFromAddress(uint64_t address) { | 146 GlobalActivityAnalyzer::GetProgramLocationFromAddress(uint64_t address) { |
| 88 // TODO(bcwhite): Implement this. | 147 // TODO(bcwhite): Implement this. |
| 89 return { 0, 0 }; | 148 return { 0, 0 }; |
| 90 } | 149 } |
| 91 | 150 |
| 92 void GlobalActivityAnalyzer::PrepareAllAnalyzers() { | 151 void GlobalActivityAnalyzer::PrepareAllAnalyzers() { |
| 93 // Fetch all the records. This will retrieve only ones created since the | 152 // Fetch all the records. This will retrieve only ones created since the |
| 94 // last run since the PMA iterator will continue from where it left off. | 153 // last run since the PMA iterator will continue from where it left off. |
| 95 uint32_t type; | 154 uint32_t type; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 116 if (!base) | 175 if (!base) |
| 117 continue; | 176 continue; |
| 118 | 177 |
| 119 // Create the analyzer on the data. This will capture a snapshot of the | 178 // Create the analyzer on the data. This will capture a snapshot of the |
| 120 // tracker state. This can fail if the tracker is somehow corrupted or is | 179 // tracker state. This can fail if the tracker is somehow corrupted or is |
| 121 // in the process of shutting down. | 180 // in the process of shutting down. |
| 122 std::unique_ptr<ThreadActivityAnalyzer> analyzer(new ThreadActivityAnalyzer( | 181 std::unique_ptr<ThreadActivityAnalyzer> analyzer(new ThreadActivityAnalyzer( |
| 123 base, allocator_->GetAllocSize(tracker_ref))); | 182 base, allocator_->GetAllocSize(tracker_ref))); |
| 124 if (!analyzer->IsValid()) | 183 if (!analyzer->IsValid()) |
| 125 continue; | 184 continue; |
| 185 analyzer->AddGlobalInformation(this); | |
| 126 | 186 |
| 127 // Add this analyzer to the map of known ones, indexed by a unique thread | 187 // Add this analyzer to the map of known ones, indexed by a unique thread |
| 128 // identifier. | 188 // identifier. |
| 129 DCHECK(!base::ContainsKey(analyzers_, analyzer->GetThreadKey())); | 189 DCHECK(!base::ContainsKey(analyzers_, analyzer->GetThreadKey())); |
| 130 analyzer->allocator_reference_ = ref; | 190 analyzer->allocator_reference_ = ref; |
| 131 analyzers_[analyzer->GetThreadKey()] = std::move(analyzer); | 191 analyzers_[analyzer->GetThreadKey()] = std::move(analyzer); |
| 132 } | 192 } |
| 133 } | 193 } |
| 134 | 194 |
| 135 } // namespace debug | 195 } // namespace debug |
| 136 } // namespace base | 196 } // namespace base |
| OLD | NEW |