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 |