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 |