OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/trace_event/memory_dump_manager.h" | 5 #include "base/trace_event/memory_dump_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/allocator/features.h" | 10 #include "base/allocator/features.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 | 40 |
41 namespace { | 41 namespace { |
42 | 42 |
43 const int kTraceEventNumArgs = 1; | 43 const int kTraceEventNumArgs = 1; |
44 const char* kTraceEventArgNames[] = {"dumps"}; | 44 const char* kTraceEventArgNames[] = {"dumps"}; |
45 const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE}; | 45 const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE}; |
46 | 46 |
47 StaticAtomicSequenceNumber g_next_guid; | 47 StaticAtomicSequenceNumber g_next_guid; |
48 MemoryDumpManager* g_instance_for_testing = nullptr; | 48 MemoryDumpManager* g_instance_for_testing = nullptr; |
49 | 49 |
| 50 // The list of names of dump providers that are blacklisted from strict thread |
| 51 // affinity check on unregistration. These providers could potentially cause |
| 52 // crashes on build bots if they do not unregister on right thread. |
| 53 // TODO(ssid): Fix all the dump providers to unregister if needed and clear the |
| 54 // blacklist, crbug.com/643438. |
| 55 const char* const kStrictThreadCheckBlacklist[] = { |
| 56 "android::ResourceManagerImpl", |
| 57 "AndroidGraphics", |
| 58 "BrowserGpuMemoryBufferManager", |
| 59 "ClientDiscardableSharedMemoryManager", |
| 60 "ContextProviderCommandBuffer", |
| 61 "DOMStorage", |
| 62 "DiscardableSharedMemoryManager", |
| 63 "FontCaches", |
| 64 "GpuMemoryBufferVideoFramePool", |
| 65 "IndexedDBBackingStore", |
| 66 "LeveldbValueStore", |
| 67 "MemoryCache", |
| 68 "Skia", |
| 69 "Sql", |
| 70 "ThreadLocalEventBuffer", |
| 71 "TraceLog", |
| 72 "URLRequestContext", |
| 73 "V8Isolate", |
| 74 "VpxVideoDecoder", |
| 75 "cc::ResourcePool", |
| 76 "cc::ResourceProvider", |
| 77 "cc::SoftwareImageDecodeCache", |
| 78 "cc::StagingBufferPool", |
| 79 "gpu::BufferManager", |
| 80 "gpu::MappedMemoryManager", |
| 81 "gpu::RenderbufferManager", |
| 82 "gpu::TextureManager", |
| 83 "gpu::TransferBufferManager", |
| 84 "sql::Connection", |
| 85 "SyncDirectory", |
| 86 "BlacklistTestDumpProvider" // for testing |
| 87 }; |
| 88 |
50 // Callback wrapper to hook upon the completion of RequestGlobalDump() and | 89 // Callback wrapper to hook upon the completion of RequestGlobalDump() and |
51 // inject trace markers. | 90 // inject trace markers. |
52 void OnGlobalDumpDone(MemoryDumpCallback wrapped_callback, | 91 void OnGlobalDumpDone(MemoryDumpCallback wrapped_callback, |
53 uint64_t dump_guid, | 92 uint64_t dump_guid, |
54 bool success) { | 93 bool success) { |
55 TRACE_EVENT_NESTABLE_ASYNC_END1( | 94 TRACE_EVENT_NESTABLE_ASYNC_END1( |
56 MemoryDumpManager::kTraceCategory, "GlobalMemoryDump", | 95 MemoryDumpManager::kTraceCategory, "GlobalMemoryDump", |
57 TRACE_ID_MANGLE(dump_guid), "success", success); | 96 TRACE_ID_MANGLE(dump_guid), "success", success); |
58 | 97 |
59 if (!wrapped_callback.is_null()) { | 98 if (!wrapped_callback.is_null()) { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 is_coordinator_(false), | 170 is_coordinator_(false), |
132 memory_tracing_enabled_(0), | 171 memory_tracing_enabled_(0), |
133 tracing_process_id_(kInvalidTracingProcessId), | 172 tracing_process_id_(kInvalidTracingProcessId), |
134 dumper_registrations_ignored_for_testing_(false), | 173 dumper_registrations_ignored_for_testing_(false), |
135 heap_profiling_enabled_(false) { | 174 heap_profiling_enabled_(false) { |
136 g_next_guid.GetNext(); // Make sure that first guid is not zero. | 175 g_next_guid.GetNext(); // Make sure that first guid is not zero. |
137 | 176 |
138 // At this point the command line may not be initialized but we try to | 177 // At this point the command line may not be initialized but we try to |
139 // enable the heap profiler to capture allocations as soon as possible. | 178 // enable the heap profiler to capture allocations as soon as possible. |
140 EnableHeapProfilingIfNeeded(); | 179 EnableHeapProfilingIfNeeded(); |
| 180 |
| 181 strict_thread_check_blacklist_.insert(std::begin(kStrictThreadCheckBlacklist), |
| 182 std::end(kStrictThreadCheckBlacklist)); |
141 } | 183 } |
142 | 184 |
143 MemoryDumpManager::~MemoryDumpManager() { | 185 MemoryDumpManager::~MemoryDumpManager() { |
144 TraceLog::GetInstance()->RemoveEnabledStateObserver(this); | 186 TraceLog::GetInstance()->RemoveEnabledStateObserver(this); |
145 } | 187 } |
146 | 188 |
147 void MemoryDumpManager::EnableHeapProfilingIfNeeded() { | 189 void MemoryDumpManager::EnableHeapProfilingIfNeeded() { |
148 if (heap_profiling_enabled_) | 190 if (heap_profiling_enabled_) |
149 return; | 191 return; |
150 | 192 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 return; // Not registered / already unregistered. | 374 return; // Not registered / already unregistered. |
333 | 375 |
334 if (take_mdp_ownership_and_delete_async) { | 376 if (take_mdp_ownership_and_delete_async) { |
335 // The MDP will be deleted whenever the MDPInfo struct will, that is either: | 377 // The MDP will be deleted whenever the MDPInfo struct will, that is either: |
336 // - At the end of this function, if no dump is in progress. | 378 // - At the end of this function, if no dump is in progress. |
337 // - Either in SetupNextMemoryDump() or InvokeOnMemoryDump() when MDPInfo is | 379 // - Either in SetupNextMemoryDump() or InvokeOnMemoryDump() when MDPInfo is |
338 // removed from |pending_dump_providers|. | 380 // removed from |pending_dump_providers|. |
339 // - When the provider is removed from |dump_providers_for_polling_|. | 381 // - When the provider is removed from |dump_providers_for_polling_|. |
340 DCHECK(!(*mdp_iter)->owned_dump_provider); | 382 DCHECK(!(*mdp_iter)->owned_dump_provider); |
341 (*mdp_iter)->owned_dump_provider = std::move(owned_mdp); | 383 (*mdp_iter)->owned_dump_provider = std::move(owned_mdp); |
342 } else if (subtle::NoBarrier_Load(&memory_tracing_enabled_)) { | 384 } else if (strict_thread_check_blacklist_.count((*mdp_iter)->name) == 0 || |
| 385 subtle::NoBarrier_Load(&memory_tracing_enabled_)) { |
| 386 // If dump provider's name is on |strict_thread_check_blacklist_|, then the |
| 387 // DCHECK is fired only when tracing is enabled. Otherwise the DCHECK is |
| 388 // fired even when tracing is not enabled (stricter). |
| 389 // TODO(ssid): Remove this condition after removing all the dump providers |
| 390 // in the blacklist and the buildbots are no longer flakily hitting the |
| 391 // DCHECK, crbug.com/643438. |
| 392 |
343 // If you hit this DCHECK, your dump provider has a bug. | 393 // If you hit this DCHECK, your dump provider has a bug. |
344 // Unregistration of a MemoryDumpProvider is safe only if: | 394 // Unregistration of a MemoryDumpProvider is safe only if: |
345 // - The MDP has specified a sequenced task runner affinity AND the | 395 // - The MDP has specified a sequenced task runner affinity AND the |
346 // unregistration happens on the same task runner. So that the MDP cannot | 396 // unregistration happens on the same task runner. So that the MDP cannot |
347 // unregister and be in the middle of a OnMemoryDump() at the same time. | 397 // unregister and be in the middle of a OnMemoryDump() at the same time. |
348 // - The MDP has NOT specified a task runner affinity and its ownership is | 398 // - The MDP has NOT specified a task runner affinity and its ownership is |
349 // transferred via UnregisterAndDeleteDumpProviderSoon(). | 399 // transferred via UnregisterAndDeleteDumpProviderSoon(). |
350 // In all the other cases, it is not possible to guarantee that the | 400 // In all the other cases, it is not possible to guarantee that the |
351 // unregistration will not race with OnMemoryDump() calls. | 401 // unregistration will not race with OnMemoryDump() calls. |
352 DCHECK((*mdp_iter)->task_runner && | 402 DCHECK((*mdp_iter)->task_runner && |
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
956 if (heavy_dump_rate_ > 0 && periodic_dumps_count_ % heavy_dump_rate_ == 0) | 1006 if (heavy_dump_rate_ > 0 && periodic_dumps_count_ % heavy_dump_rate_ == 0) |
957 level_of_detail = MemoryDumpLevelOfDetail::DETAILED; | 1007 level_of_detail = MemoryDumpLevelOfDetail::DETAILED; |
958 ++periodic_dumps_count_; | 1008 ++periodic_dumps_count_; |
959 | 1009 |
960 MemoryDumpManager::GetInstance()->RequestGlobalDump( | 1010 MemoryDumpManager::GetInstance()->RequestGlobalDump( |
961 MemoryDumpType::PERIODIC_INTERVAL, level_of_detail); | 1011 MemoryDumpType::PERIODIC_INTERVAL, level_of_detail); |
962 } | 1012 } |
963 | 1013 |
964 } // namespace trace_event | 1014 } // namespace trace_event |
965 } // namespace base | 1015 } // namespace base |
OLD | NEW |