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

Side by Side Diff: components/keyed_service/core/dependency_manager.cc

Issue 2749823002: Restore KeyedServiceFactory diagnostics for context use-after-destroy. (Closed)
Patch Set: Refactor SiteEngagementService tests. Created 3 years, 9 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/keyed_service/core/dependency_manager.h" 5 #include "components/keyed_service/core/dependency_manager.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/dump_without_crashing.h"
8 #include "base/logging.h" 9 #include "base/logging.h"
9 #include "base/supports_user_data.h" 10 #include "base/supports_user_data.h"
10 #include "components/keyed_service/core/keyed_service_base_factory.h" 11 #include "components/keyed_service/core/keyed_service_base_factory.h"
11 12
12 #ifndef NDEBUG 13 #ifndef NDEBUG
13 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
14 #include "base/files/file_util.h" 15 #include "base/files/file_util.h"
15 #endif // NDEBUG 16 #endif // NDEBUG
16 17
17 DependencyManager::DependencyManager() { 18 DependencyManager::DependencyManager() {
(...skipping 25 matching lines...) Expand all
43 44
44 for (auto* dependency_node : construction_order) { 45 for (auto* dependency_node : construction_order) {
45 KeyedServiceBaseFactory* factory = 46 KeyedServiceBaseFactory* factory =
46 static_cast<KeyedServiceBaseFactory*>(dependency_node); 47 static_cast<KeyedServiceBaseFactory*>(dependency_node);
47 factory->RegisterPrefsIfNecessaryForContext(context, pref_registry); 48 factory->RegisterPrefsIfNecessaryForContext(context, pref_registry);
48 } 49 }
49 } 50 }
50 51
51 void DependencyManager::CreateContextServices(base::SupportsUserData* context, 52 void DependencyManager::CreateContextServices(base::SupportsUserData* context,
52 bool is_testing_context) { 53 bool is_testing_context) {
53 #ifndef NDEBUG 54 MarkContextLive(context);
54 MarkContextLiveForTesting(context);
55 #endif
56 55
57 std::vector<DependencyNode*> construction_order; 56 std::vector<DependencyNode*> construction_order;
58 if (!dependency_graph_.GetConstructionOrder(&construction_order)) { 57 if (!dependency_graph_.GetConstructionOrder(&construction_order)) {
59 NOTREACHED(); 58 NOTREACHED();
60 } 59 }
61 60
62 #ifndef NDEBUG 61 #ifndef NDEBUG
63 DumpContextDependencies(context); 62 DumpContextDependencies(context);
64 #endif 63 #endif
65 64
(...skipping 19 matching lines...) Expand all
85 #ifndef NDEBUG 84 #ifndef NDEBUG
86 DumpContextDependencies(context); 85 DumpContextDependencies(context);
87 #endif 86 #endif
88 87
89 for (auto* dependency_node : destruction_order) { 88 for (auto* dependency_node : destruction_order) {
90 KeyedServiceBaseFactory* factory = 89 KeyedServiceBaseFactory* factory =
91 static_cast<KeyedServiceBaseFactory*>(dependency_node); 90 static_cast<KeyedServiceBaseFactory*>(dependency_node);
92 factory->ContextShutdown(context); 91 factory->ContextShutdown(context);
93 } 92 }
94 93
95 #ifndef NDEBUG
96 // The context is now dead to the rest of the program. 94 // The context is now dead to the rest of the program.
97 dead_context_pointers_.insert(context); 95 dead_context_pointers_.insert(context);
98 #endif
99 96
100 for (auto* dependency_node : destruction_order) { 97 for (auto* dependency_node : destruction_order) {
101 KeyedServiceBaseFactory* factory = 98 KeyedServiceBaseFactory* factory =
102 static_cast<KeyedServiceBaseFactory*>(dependency_node); 99 static_cast<KeyedServiceBaseFactory*>(dependency_node);
103 factory->ContextDestroyed(context); 100 factory->ContextDestroyed(context);
104 } 101 }
105 } 102 }
106 103
107 #ifndef NDEBUG
108 void DependencyManager::AssertContextWasntDestroyed( 104 void DependencyManager::AssertContextWasntDestroyed(
109 base::SupportsUserData* context) { 105 base::SupportsUserData* context) const {
110 if (dead_context_pointers_.find(context) != dead_context_pointers_.end()) { 106 if (dead_context_pointers_.find(context) != dead_context_pointers_.end()) {
107 #if DCHECK_IS_ON()
111 NOTREACHED() << "Attempted to access a context that was ShutDown(). " 108 NOTREACHED() << "Attempted to access a context that was ShutDown(). "
112 << "This is most likely a heap smasher in progress. After " 109 << "This is most likely a heap smasher in progress. After "
113 << "KeyedService::Shutdown() completes, your service MUST " 110 << "KeyedService::Shutdown() completes, your service MUST "
114 << "NOT refer to depended services again."; 111 << "NOT refer to depended services again.";
112 #else // DCHECK_IS_ON()
113 // We want to see all possible use-after-destroy in production environment.
114 base::debug::DumpWithoutCrashing();
115 #endif // DCHECK_IS_ON()
115 } 116 }
116 } 117 }
117 118
118 void DependencyManager::MarkContextLiveForTesting( 119 void DependencyManager::MarkContextLive(base::SupportsUserData* context) {
119 base::SupportsUserData* context) {
120 dead_context_pointers_.erase(context); 120 dead_context_pointers_.erase(context);
121 } 121 }
122 122
123 #ifndef NDEBUG
123 namespace { 124 namespace {
124 125
125 std::string KeyedServiceBaseFactoryGetNodeName(DependencyNode* node) { 126 std::string KeyedServiceBaseFactoryGetNodeName(DependencyNode* node) {
126 return static_cast<KeyedServiceBaseFactory*>(node)->name(); 127 return static_cast<KeyedServiceBaseFactory*>(node)->name();
127 } 128 }
128 129
129 } // namespace 130 } // namespace
130 131
131 void DependencyManager::DumpDependenciesAsGraphviz( 132 void DependencyManager::DumpDependenciesAsGraphviz(
132 const std::string& top_level_name, 133 const std::string& top_level_name,
133 const base::FilePath& dot_file) const { 134 const base::FilePath& dot_file) const {
134 DCHECK(!dot_file.empty()); 135 DCHECK(!dot_file.empty());
135 std::string contents = dependency_graph_.DumpAsGraphviz( 136 std::string contents = dependency_graph_.DumpAsGraphviz(
136 top_level_name, base::Bind(&KeyedServiceBaseFactoryGetNodeName)); 137 top_level_name, base::Bind(&KeyedServiceBaseFactoryGetNodeName));
137 base::WriteFile(dot_file, contents.c_str(), contents.size()); 138 base::WriteFile(dot_file, contents.c_str(), contents.size());
138 } 139 }
139 #endif // NDEBUG 140 #endif // NDEBUG
OLDNEW
« no previous file with comments | « components/keyed_service/core/dependency_manager.h ('k') | components/keyed_service/core/keyed_service_base_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698