Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(486)

Side by Side Diff: base/debug/activity_analyzer.cc

Issue 1980743002: Track thread activities in order to diagnose hangs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@readwrite-mmf
Patch Set: addressed minor review comments; added ownership Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "base/debug/activity_analyzer.h"
6
7 #include "base/files/file.h"
8 #include "base/files/file_path.h"
9 #include "base/files/memory_mapped_file.h"
10 #include "base/logging.h"
11 #include "base/memory/ptr_util.h"
12 #include "base/stl_util.h"
13 #include "base/strings/string_util.h"
14
15 namespace base {
16 namespace debug {
17
18 ThreadActivityAnalyzer::ThreadActivityAnalyzer(
19 const ThreadActivityTracker& tracker)
20 : activity_snapshot_valid_(tracker.Snapshot(&activity_snapshot_)) {}
21
22 ThreadActivityAnalyzer::ThreadActivityAnalyzer(void* base, size_t size)
23 : ThreadActivityAnalyzer(ThreadActivityTracker(base, size)) {}
24
25 ThreadActivityAnalyzer::ThreadActivityAnalyzer(
26 PersistentMemoryAllocator* allocator,
27 PersistentMemoryAllocator::Reference reference)
28 : ThreadActivityAnalyzer(allocator->GetAsObject<char>(
29 reference,
30 GlobalActivityTracker::kTypeIdActivityTracker),
31 allocator->GetAllocSize(reference)) {}
32
33 ThreadActivityAnalyzer::~ThreadActivityAnalyzer() {}
34
35 GlobalActivityAnalyzer::GlobalActivityAnalyzer(
36 std::unique_ptr<PersistentMemoryAllocator> allocator)
37 : allocator_(std::move(allocator)), allocator_iterator_(allocator_.get()) {}
38
39 GlobalActivityAnalyzer::~GlobalActivityAnalyzer() {}
40
41 #if !defined(OS_NACL)
42 std::unique_ptr<GlobalActivityAnalyzer> GlobalActivityAnalyzer::CreateWithFile(
43 const FilePath& file_path) {
44 std::unique_ptr<MemoryMappedFile> mmfile(new MemoryMappedFile());
45 mmfile->Initialize(file_path);
manzagop (departed) 2016/08/03 14:36:06 // Note: write access is required for snapshotting
bcwhite 2016/08/04 14:06:20 Good point. Done.
46 if (!mmfile->IsValid())
47 return nullptr;
48
49 if (!FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile, true))
50 return nullptr;
51
52 return WrapUnique(new GlobalActivityAnalyzer(
53 WrapUnique(new FilePersistentMemoryAllocator(
54 std::move(mmfile), 0, 0, base::StringPiece(),
55 true))));
56 }
57 #endif // !defined(OS_NACL)
58
59 ThreadActivityAnalyzer* GlobalActivityAnalyzer::GetFirstAnalyzer() {
60 PrepareAllAnalyzers();
61 analyzers_iterator_ = analyzers_.begin();
62 if (analyzers_iterator_ == analyzers_.end())
63 return nullptr;
64 return analyzers_iterator_->second.get();
65 }
66
67 ThreadActivityAnalyzer* GlobalActivityAnalyzer::GetNextAnalyzer() {
68 DCHECK(analyzers_iterator_ != analyzers_.end());
69 ++analyzers_iterator_;
70 if (analyzers_iterator_ == analyzers_.end())
71 return nullptr;
72 return analyzers_iterator_->second.get();
73 }
74
75 ThreadActivityAnalyzer* GlobalActivityAnalyzer::GetAnalyzerForThread(
76 const ThreadKey& key) {
77 auto found = analyzers_.find(key);
78 if (found == analyzers_.end())
79 return nullptr;
80 return found->second.get();
81 }
82
83 void GlobalActivityAnalyzer::PrepareAllAnalyzers() {
84 // Fetch all the records. This will retrieve only ones created since the
85 // last run since the PMA iterator will continue from where it left off.
86 uint32_t type;
87 PersistentMemoryAllocator::Reference ref;
88 while ((ref = allocator_iterator_.GetNext(&type)) != 0) {
89 switch (type) {
90 case GlobalActivityTracker::kTypeIdActivityTracker:
91 case GlobalActivityTracker::kTypeIdActivityTrackerFree:
92 // Free or not, add it to the list of references for later analysis.
93 tracker_references_.insert(ref);
94 break;
95 }
96 }
97
98 // Go through all the known references and create analyzers for them with
99 // snapshots of the current state.
100 analyzers_.clear();
101 for (PersistentMemoryAllocator::Reference tracker_ref : tracker_references_) {
102 // Get the actual data segment for the tracker. This can fail if the
103 // record has been marked "free" since the type will not match.
104 void* base = allocator_->GetAsObject<char>(
105 tracker_ref, GlobalActivityTracker::kTypeIdActivityTracker);
106 if (!base)
107 continue;
108
109 // Create the analyzer on the data. This will capture a snapshot of the
110 // tracker state. This can fail if the tracker is somehow corrupted or is
111 // in the process of shutting down.
112 std::unique_ptr<ThreadActivityAnalyzer> analyzer(new ThreadActivityAnalyzer(
113 base, allocator_->GetAllocSize(tracker_ref)));
114 if (!analyzer->IsValid())
115 continue;
116
117 // Add this analyzer to the map of known ones, indexed by a unique thread
118 // identifier.
119 DCHECK(!ContainsKey(analyzers_, analyzer->GetThreadKey()));
120 analyzer->allocator_reference_ = ref;
121 analyzers_[analyzer->GetThreadKey()] = std::move(analyzer);
122 }
123 }
124
125 } // namespace debug
126 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698