| 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 <inttypes.h> | 7 #include <inttypes.h> |
| 8 #include <stdio.h> | 8 #include <stdio.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 #endif | 47 #endif |
| 48 | 48 |
| 49 namespace base { | 49 namespace base { |
| 50 namespace trace_event { | 50 namespace trace_event { |
| 51 | 51 |
| 52 namespace { | 52 namespace { |
| 53 | 53 |
| 54 StaticAtomicSequenceNumber g_next_guid; | 54 StaticAtomicSequenceNumber g_next_guid; |
| 55 MemoryDumpManager* g_instance_for_testing = nullptr; | 55 MemoryDumpManager* g_instance_for_testing = nullptr; |
| 56 | 56 |
| 57 // The list of names of dump providers that are blacklisted from strict thread | |
| 58 // affinity check on unregistration. These providers could potentially cause | |
| 59 // crashes on build bots if they do not unregister on right thread. | |
| 60 // TODO(ssid): Fix all the dump providers to unregister if needed and clear the | |
| 61 // blacklist, crbug.com/643438. | |
| 62 const char* const kStrictThreadCheckBlacklist[] = { | |
| 63 "ClientDiscardableSharedMemoryManager", | |
| 64 "ContextProviderCommandBuffer", | |
| 65 "DiscardableSharedMemoryManager", | |
| 66 "FontCaches", | |
| 67 "GpuMemoryBufferVideoFramePool", | |
| 68 "IndexedDBBackingStore", | |
| 69 "Sql", | |
| 70 "ThreadLocalEventBuffer", | |
| 71 "TraceLog", | |
| 72 "URLRequestContext", | |
| 73 "VpxVideoDecoder", | |
| 74 "cc::SoftwareImageDecodeCache", | |
| 75 "cc::StagingBufferPool", | |
| 76 "gpu::BufferManager", | |
| 77 "gpu::MappedMemoryManager", | |
| 78 "gpu::RenderbufferManager", | |
| 79 "BlacklistTestDumpProvider" // for testing | |
| 80 }; | |
| 81 | |
| 82 // Callback wrapper to hook upon the completion of RequestGlobalDump() and | 57 // Callback wrapper to hook upon the completion of RequestGlobalDump() and |
| 83 // inject trace markers. | 58 // inject trace markers. |
| 84 void OnGlobalDumpDone(GlobalMemoryDumpCallback wrapped_callback, | 59 void OnGlobalDumpDone(GlobalMemoryDumpCallback wrapped_callback, |
| 85 uint64_t dump_guid, | 60 uint64_t dump_guid, |
| 86 bool success) { | 61 bool success) { |
| 87 char guid_str[20]; | 62 char guid_str[20]; |
| 88 sprintf(guid_str, "0x%" PRIx64, dump_guid); | 63 sprintf(guid_str, "0x%" PRIx64, dump_guid); |
| 89 TRACE_EVENT_NESTABLE_ASYNC_END2(MemoryDumpManager::kTraceCategory, | 64 TRACE_EVENT_NESTABLE_ASYNC_END2(MemoryDumpManager::kTraceCategory, |
| 90 "GlobalMemoryDump", TRACE_ID_LOCAL(dump_guid), | 65 "GlobalMemoryDump", TRACE_ID_LOCAL(dump_guid), |
| 91 "dump_guid", TRACE_STR_COPY(guid_str), | 66 "dump_guid", TRACE_STR_COPY(guid_str), |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 : is_coordinator_(false), | 159 : is_coordinator_(false), |
| 185 is_enabled_(0), | 160 is_enabled_(0), |
| 186 tracing_process_id_(kInvalidTracingProcessId), | 161 tracing_process_id_(kInvalidTracingProcessId), |
| 187 dumper_registrations_ignored_for_testing_(false), | 162 dumper_registrations_ignored_for_testing_(false), |
| 188 heap_profiling_enabled_(false) { | 163 heap_profiling_enabled_(false) { |
| 189 g_next_guid.GetNext(); // Make sure that first guid is not zero. | 164 g_next_guid.GetNext(); // Make sure that first guid is not zero. |
| 190 | 165 |
| 191 // At this point the command line may not be initialized but we try to | 166 // At this point the command line may not be initialized but we try to |
| 192 // enable the heap profiler to capture allocations as soon as possible. | 167 // enable the heap profiler to capture allocations as soon as possible. |
| 193 EnableHeapProfilingIfNeeded(); | 168 EnableHeapProfilingIfNeeded(); |
| 194 | |
| 195 strict_thread_check_blacklist_.insert(std::begin(kStrictThreadCheckBlacklist), | |
| 196 std::end(kStrictThreadCheckBlacklist)); | |
| 197 } | 169 } |
| 198 | 170 |
| 199 MemoryDumpManager::~MemoryDumpManager() { | 171 MemoryDumpManager::~MemoryDumpManager() { |
| 200 AutoLock lock(lock_); | 172 AutoLock lock(lock_); |
| 201 if (dump_thread_) { | 173 if (dump_thread_) { |
| 202 dump_thread_->Stop(); | 174 dump_thread_->Stop(); |
| 203 dump_thread_.reset(); | 175 dump_thread_.reset(); |
| 204 } | 176 } |
| 205 } | 177 } |
| 206 | 178 |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 return; // Not registered / already unregistered. | 363 return; // Not registered / already unregistered. |
| 392 | 364 |
| 393 if (take_mdp_ownership_and_delete_async) { | 365 if (take_mdp_ownership_and_delete_async) { |
| 394 // The MDP will be deleted whenever the MDPInfo struct will, that is either: | 366 // The MDP will be deleted whenever the MDPInfo struct will, that is either: |
| 395 // - At the end of this function, if no dump is in progress. | 367 // - At the end of this function, if no dump is in progress. |
| 396 // - Either in SetupNextMemoryDump() or InvokeOnMemoryDump() when MDPInfo is | 368 // - Either in SetupNextMemoryDump() or InvokeOnMemoryDump() when MDPInfo is |
| 397 // removed from |pending_dump_providers|. | 369 // removed from |pending_dump_providers|. |
| 398 // - When the provider is removed from other clients (MemoryPeakDetector). | 370 // - When the provider is removed from other clients (MemoryPeakDetector). |
| 399 DCHECK(!(*mdp_iter)->owned_dump_provider); | 371 DCHECK(!(*mdp_iter)->owned_dump_provider); |
| 400 (*mdp_iter)->owned_dump_provider = std::move(owned_mdp); | 372 (*mdp_iter)->owned_dump_provider = std::move(owned_mdp); |
| 401 } else if (strict_thread_check_blacklist_.count((*mdp_iter)->name) == 0 || | 373 } else { |
| 402 subtle::NoBarrier_Load(&is_enabled_)) { | |
| 403 // If dump provider's name is on |strict_thread_check_blacklist_|, then the | |
| 404 // DCHECK is fired only when tracing is enabled. Otherwise the DCHECK is | |
| 405 // fired even when tracing is not enabled (stricter). | |
| 406 // TODO(ssid): Remove this condition after removing all the dump providers | |
| 407 // in the blacklist and the buildbots are no longer flakily hitting the | |
| 408 // DCHECK, crbug.com/643438. | |
| 409 | |
| 410 // If you hit this DCHECK, your dump provider has a bug. | 374 // If you hit this DCHECK, your dump provider has a bug. |
| 411 // Unregistration of a MemoryDumpProvider is safe only if: | 375 // Unregistration of a MemoryDumpProvider is safe only if: |
| 412 // - The MDP has specified a sequenced task runner affinity AND the | 376 // - The MDP has specified a sequenced task runner affinity AND the |
| 413 // unregistration happens on the same task runner. So that the MDP cannot | 377 // unregistration happens on the same task runner. So that the MDP cannot |
| 414 // unregister and be in the middle of a OnMemoryDump() at the same time. | 378 // unregister and be in the middle of a OnMemoryDump() at the same time. |
| 415 // - The MDP has NOT specified a task runner affinity and its ownership is | 379 // - The MDP has NOT specified a task runner affinity and its ownership is |
| 416 // transferred via UnregisterAndDeleteDumpProviderSoon(). | 380 // transferred via UnregisterAndDeleteDumpProviderSoon(). |
| 417 // In all the other cases, it is not possible to guarantee that the | 381 // In all the other cases, it is not possible to guarantee that the |
| 418 // unregistration will not race with OnMemoryDump() calls. | 382 // unregistration will not race with OnMemoryDump() calls. |
| 419 DCHECK((*mdp_iter)->task_runner && | 383 DCHECK((*mdp_iter)->task_runner && |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 941 if (iter == process_dumps.end()) { | 905 if (iter == process_dumps.end()) { |
| 942 std::unique_ptr<ProcessMemoryDump> new_pmd( | 906 std::unique_ptr<ProcessMemoryDump> new_pmd( |
| 943 new ProcessMemoryDump(session_state, dump_args)); | 907 new ProcessMemoryDump(session_state, dump_args)); |
| 944 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; | 908 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; |
| 945 } | 909 } |
| 946 return iter->second.get(); | 910 return iter->second.get(); |
| 947 } | 911 } |
| 948 | 912 |
| 949 } // namespace trace_event | 913 } // namespace trace_event |
| 950 } // namespace base | 914 } // namespace base |
| OLD | NEW |