1 // Copyright 2016 The Chromium Authors
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/trace_event/memory_infra_background_allowlist.h"
6
7 #include <string.h>
8
9 #include <string>
10 #include <string_view>
11
12 #include "base/containers/fixed_flat_set.h"
13 #include "base/strings/string_util.h"
14 #include "build/build_config.h"
15 #include "partition_alloc/partition_alloc_buildflags.h"
16 #include "third_party/abseil-cpp/absl/strings/ascii.h"
17
18 #if BUILDFLAG(IS_ANDROID)
19 #include "base/android/meminfo_dump_provider.h"
20 #endif
21
22 namespace base {
23 namespace trace_event {
24 namespace {
25
26 // The names of dump providers allowed to perform background tracing. Dump
27 // providers can be added here only if the background mode dump has very
28 // little processor and memory overhead.
29 // TODO(ssid): Some dump providers do not create ownership edges on background
30 // dump. So, the effective size will not be correct.
31 constexpr auto kDumpProviderAllowlist =
32 base::MakeFixedFlatSet<std::string_view>({
33 // clang-format off
34 #if BUILDFLAG(IS_ANDROID)
35 base::android::MeminfoDumpProvider::kDumpProviderName,
36 "android::ResourceManagerImpl",
37 #endif
38 "AutocompleteController",
39 "AXPlatformNode",
40 "BlinkGC",
41 "BlinkObjectCounters",
42 "BlobStorageContext",
43 "Canvas",
44 "ClientDiscardableSharedMemoryManager",
45 #if BUILDFLAG(IS_MAC)
46 "CommandBuffer",
47 #endif
48 "ContextProviderCommandBuffer",
49 "DOMStorage",
50 "DevTools",
51 "DiscardableSharedMemoryManager",
52 "DownloadService",
53 "ExtensionFunctions",
54 "FontCaches",
55 "FrameEvictionManager",
56 "GrShaderCache",
57 "HistoryReport",
58 "cc::ResourcePool",
59 "gpu::BufferManager",
60 "gpu::RenderbufferManager",
61 "gpu::ServiceDiscardableManager",
62 "gpu::ServiceTransferCache",
63 "gpu::SharedImageStub",
64 "gpu::TextureManager",
65 "hibernated_canvas",
66 "vulkan",
67 "IPCChannel",
68 "InMemoryURLIndex",
69 "IndexedDBBackingStore",
70 "IndexedDBFactoryImpl",
71 "JavaHeap",
72 "LevelDB",
73 "LeveldbValueStore",
74 "LocalStorage",
75 "MadvFreeDiscardableMemoryAllocator",
76 "Malloc",
77 "ManualFillingCache",
78 "MemoryCache",
79 "MojoHandleTable",
80 "MojoLevelDB",
81 "MojoMessages",
82 "PartitionAlloc",
83 "PartitionAlloc.AddressSpace",
84 "ProcessMemoryMetrics",
85 "SharedContextState",
86 "SharedImageManager",
87 "SharedMemoryTracker",
88 "Skia",
89 "Sql",
90 "TabRestoreServiceHelper",
91 "TextureOwner"
92 "URLRequestContext",
93 "V8Isolate",
94 "WebMediaPlayer_MainThread",
95 "WebMediaPlayer_MediaThread",
96 // clang-format on
97 });
98
99 // A list of string names that are allowed for the memory allocator dumps in
100 // background mode.
101 constexpr auto kAllocatorDumpNameAllowlist =
102 base::MakeFixedFlatSet<std::string_view>({
103 // clang-format off
104 // Some of the blink values vary based on compile time flags. The
105 // compile time flags are not in base, so all are listed here.
106 #if BUILDFLAG(IS_ANDROID)
107 base::android::MeminfoDumpProvider::kDumpName,
108 #endif
109 "accessibility/ax_platform_node",
110 "blink_gc/main/allocated_objects",
111 "blink_gc/main/heap",
112 "blink_gc/workers/heap/worker_0x?",
113 "blink_gc/workers/worker_0x?/heap",
114 "blink_gc/workers/worker_0x?/allocated_objects",
115 "blink_objects/AdSubframe",
116 "blink_objects/ArrayBufferContents",
117 "blink_objects/AudioHandler",
118 "blink_objects/AudioWorkletProcessor",
119 "blink_objects/ContextLifecycleStateObserver",
120 "blink_objects/DetachedScriptState",
121 "blink_objects/Document",
122 "blink_objects/Frame",
123 "blink_objects/JSEventListener",
124 "blink_objects/LayoutObject",
125 "blink_objects/MediaKeySession",
126 "blink_objects/MediaKeys",
127 "blink_objects/Node",
128 "blink_objects/Resource",
129 "blink_objects/RTCPeerConnection",
130 "blink_objects/ScriptPromise",
131 "blink_objects/V8PerContextData",
132 "blink_objects/WorkerGlobalScope",
133 "blink_objects/UACSSResource",
134 "blink_objects/ResourceFetcher",
135 "canvas/hibernated",
136 "canvas/ResourceProvider/SkSurface",
137 "canvas/ResourceProvider/SkSurface/0x?",
138 "cc/tile_memory/provider_0x?",
139 "components/download/controller_0x?",
140 "devtools/file_watcher_0x?",
141 "discardable",
142 "discardable/madv_free_allocated",
143 "discardable/child_0x?",
144 "extensions/functions",
145 "extensions/value_store/Extensions.Database.Open.OriginManagedConfiguration/0x?",
146 "extensions/value_store/Extensions.Database.Open.Rules/0x?",
147 "extensions/value_store/Extensions.Database.Open.Scripts/0x?",
148 "extensions/value_store/Extensions.Database.Open.Settings/0x?",
149 "extensions/value_store/Extensions.Database.Open.State/0x?",
150 "extensions/value_store/Extensions.Database.Open.WebAppsLockScreen/0x?",
151 "extensions/value_store/Extensions.Database.Open/0x?",
152 "extensions/value_store/Extensions.Database.Restore/0x?",
153 "extensions/value_store/Extensions.Database.Value.Restore/0x?",
154 "font_caches/font_platform_data_cache",
155 "font_caches/shape_caches",
156 "frame_evictor",
157 "gpu/command_buffer_memory/buffer_0x?",
158 "gpu/discardable_cache/cache_0x?",
159 "gpu/discardable_cache/cache_0x?/avg_image_size",
160 "gpu/gl/buffers/context_group_0x?",
161 "gpu/gl/renderbuffers/context_group_0x?",
162 "gpu/gl/textures/context_group_0x?",
163 "gpu/gr_shader_cache/cache_0x?",
164 "gpu/mapped_memory/manager_0x?",
165 "gpu/shared_images",
166 "gpu/media_texture_owner_?",
167 "gpu/transfer_buffer_memory/buffer_0x?",
168 "gpu/transfer_cache/cache_0x?",
169 "gpu/transfer_cache/cache_0x?/avg_image_size",
170 "gpu/vulkan/vma_allocator_0x?",
171 "history/delta_file_service/leveldb_0x?",
172 "history/usage_reports_buffer/leveldb_0x?",
173 #if BUILDFLAG(IS_MAC)
174 "ioaccelerator",
175 "iosurface",
176 #endif
177 "java_heap",
178 "java_heap/allocated_objects",
179 "leveldatabase",
180 "leveldatabase/block_cache/browser",
181 "leveldatabase/block_cache/in_memory",
182 "leveldatabase/block_cache/unified",
183 "leveldatabase/block_cache/web",
184 "leveldatabase/db_0x?",
185 "leveldatabase/db_0x?/block_cache",
186 "leveldatabase/memenv_0x?",
187 "malloc",
188 "malloc/allocated_objects",
189 "malloc/metadata_fragmentation_caches",
190 #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
191 "malloc/partitions",
192 "malloc/partitions/allocator",
193 "malloc/partitions/allocator/scheduler_loop_quarantine",
194 "malloc/partitions/allocator/thread_cache",
195 "malloc/partitions/allocator/thread_cache/main_thread",
196 "malloc/partitions/aligned",
197 "malloc/partitions/original",
198 "malloc/partitions/nonscannable",
199 "malloc/partitions/nonquarantinable",
200 "malloc/sys_malloc",
201 "malloc/win_heap",
202 #endif
203 "media/webmediaplayer/audio/player_0x?",
204 "media/webmediaplayer/data_source/player_0x?",
205 "media/webmediaplayer/demuxer/player_0x?",
206 "media/webmediaplayer/video/player_0x?",
207 "media/webmediaplayer/player_0x?",
208 "mojo",
209 "mojo/data_pipe_consumer",
210 "mojo/data_pipe_producer",
211 "mojo/invitation",
212 "mojo/messages",
213 "mojo/message_pipe",
214 "mojo/platform_handle",
215 "mojo/queued_ipc_channel_message/0x?",
216 "mojo/shared_buffer",
217 "mojo/unknown",
218 "mojo/watcher",
219 "omnibox/autocomplete_controller/0x?",
220 "omnibox/in_memory_url_index/0x?",
221 "passwords/manual_filling_controller/0x?",
222 "web_cache/Image_resources",
223 "web_cache/CSS stylesheet_resources",
224 "web_cache/Script_resources",
225 "web_cache/XSL stylesheet_resources",
226 "web_cache/Font_resources",
227 "web_cache/Code_cache",
228 "web_cache/Encoded_size_duplicated_in_data_urls",
229 "web_cache/Other_resources",
230 "partition_alloc/allocated_objects",
231 "partition_alloc/address_space",
232 "partition_alloc/partitions",
233 "partition_alloc/partitions/array_buffer",
234 "partition_alloc/partitions/buffer",
235 "partition_alloc/partitions/fast_malloc",
236 #if !BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
237 "partition_alloc/partitions/fast_malloc/thread_cache",
238 "partition_alloc/partitions/fast_malloc/thread_cache/main_thread",
239 #endif
240 "partition_alloc/partitions/layout",
241 "skia/gpu_resources/context_0x?",
242 "skia/sk_glyph_cache",
243 "skia/sk_resource_cache",
244 "sqlite",
245 "ui/resource_manager_0x?/default_resource/0x?",
246 "ui/resource_manager_0x?/tinted_resource",
247 "site_storage/blob_storage/0x?",
248 "v8/main/code_stats",
249 "v8/main/contexts/detached_context",
250 "v8/main/contexts/native_context",
251 "v8/main/global_handles",
252 "v8/main/heap/code_space",
253 "v8/main/heap/code_stats",
254 "v8/main/heap/code_large_object_space",
255 "v8/main/heap/large_object_space",
256 "v8/main/heap/map_space",
257 "v8/main/heap/new_large_object_space",
258 "v8/main/heap/new_space",
259 "v8/main/heap/old_space",
260 "v8/main/heap/read_only_space",
261 "v8/main/heap/shared_large_object_space",
262 "v8/main/heap/shared_space",
263 "v8/main/heap/trusted_space",
264 "v8/main/heap/trusted_large_object_space",
265 "v8/main/malloc",
266 "v8/main/zapped_for_debug",
267 "v8/utility/code_stats",
268 "v8/utility/contexts/detached_context",
269 "v8/utility/contexts/native_context",
270 "v8/utility/global_handles",
271 "v8/utility/heap/code_space",
272 "v8/utility/heap/code_large_object_space",
273 "v8/utility/heap/large_object_space",
274 "v8/utility/heap/map_space",
275 "v8/utility/heap/new_large_object_space",
276 "v8/utility/heap/new_space",
277 "v8/utility/heap/old_space",
278 "v8/utility/heap/read_only_space",
279 "v8/utility/heap/shared_large_object_space",
280 "v8/utility/heap/shared_space",
281 "v8/utility/heap/trusted_space",
282 "v8/utility/heap/trusted_large_object_space",
283 "v8/utility/malloc",
284 "v8/utility/zapped_for_debug",
285 "v8/workers/code_stats/isolate_0x?",
286 "v8/workers/contexts/detached_context/isolate_0x?",
287 "v8/workers/contexts/native_context/isolate_0x?",
288 "v8/workers/global_handles/isolate_0x?",
289 "v8/workers/heap/code_space/isolate_0x?",
290 "v8/workers/heap/code_large_object_space/isolate_0x?",
291 "v8/workers/heap/large_object_space/isolate_0x?",
292 "v8/workers/heap/map_space/isolate_0x?",
293 "v8/workers/heap/new_large_object_space/isolate_0x?",
294 "v8/workers/heap/new_space/isolate_0x?",
295 "v8/workers/heap/old_space/isolate_0x?",
296 "v8/workers/heap/read_only_space/isolate_0x?",
297 "v8/workers/heap/shared_large_object_space/isolate_0x?",
298 "v8/workers/heap/shared_space/isolate_0x?",
299 "v8/workers/heap/trusted_space/isolate_0x?",
300 "v8/workers/heap/trusted_large_object_space/isolate_0x?",
301 "v8/workers/malloc/isolate_0x?",
302 "v8/workers/zapped_for_debug/isolate_0x?",
303 "site_storage/index_db/db_0x?",
304 "site_storage/index_db/memenv_0x?",
305 "site_storage/index_db/in_flight_0x?",
306 "site_storage/local_storage/0x?/cache_size",
307 "site_storage/localstorage/0x?/cache_size",
308 "site_storage/localstorage/0x?/leveldb",
309 "site_storage/session_storage/0x?",
310 "site_storage/session_storage/0x?/cache_size",
311 "tab_restore/service_helper_0x?/entries",
312 "tab_restore/service_helper_0x?/entries/group_0x?",
313 "tab_restore/service_helper_0x?/entries/tab_0x?",
314 "tab_restore/service_helper_0x?/entries/window_0x?",
315 "tracing/heap_profiler_blink_gc/AllocationRegister",
316 "tracing/heap_profiler_malloc/AllocationRegister",
317 "tracing/heap_profiler_partition_alloc/AllocationRegister",
318 // clang-format on
319 });
320
321 const char* const* g_dump_provider_allowlist_for_testing = nullptr;
322 const char* const* g_allocator_dump_name_allowlist_for_testing = nullptr;
323
IsNameInList(const char * name,const char * const * list)324 bool IsNameInList(const char* name, const char* const* list) {
325 for (size_t i = 0; list[i] != nullptr; ++i) {
326 if (strcmp(name, list[i]) == 0)
327 return true;
328 }
329 return false;
330 }
331
332 } // namespace
333
IsMemoryDumpProviderInAllowlist(const char * mdp_name)334 bool IsMemoryDumpProviderInAllowlist(const char* mdp_name) {
335 if (!g_dump_provider_allowlist_for_testing) {
336 return kDumpProviderAllowlist.contains(mdp_name);
337 } else {
338 return IsNameInList(mdp_name, g_dump_provider_allowlist_for_testing);
339 }
340 }
341
IsMemoryAllocatorDumpNameInAllowlist(const std::string & name)342 bool IsMemoryAllocatorDumpNameInAllowlist(const std::string& name) {
343 // Global dumps that are of hex digits are all allowed for background use.
344 if (base::StartsWith(name, "global/", CompareCase::SENSITIVE)) {
345 for (size_t i = strlen("global/"); i < name.size(); i++)
346 if (!base::IsHexDigit(name[i]))
347 return false;
348 return true;
349 }
350
351 if (base::StartsWith(name, "shared_memory/", CompareCase::SENSITIVE)) {
352 for (size_t i = strlen("shared_memory/"); i < name.size(); i++)
353 if (!base::IsHexDigit(name[i]))
354 return false;
355 return true;
356 }
357
358 // Remove special characters, numbers (including hexadecimal which are marked
359 // by '0x') from the given string.
360 const size_t length = name.size();
361 std::string stripped_str;
362 stripped_str.reserve(length);
363 bool parsing_hex = false;
364 for (size_t i = 0; i < length; ++i) {
365 if (parsing_hex &&
366 absl::ascii_isxdigit(static_cast<unsigned char>(name[i]))) {
367 continue;
368 }
369 parsing_hex = false;
370 if (i + 1 < length && name[i] == '0' && name[i + 1] == 'x') {
371 parsing_hex = true;
372 stripped_str.append("0x?");
373 ++i;
374 } else {
375 stripped_str.push_back(name[i]);
376 }
377 }
378
379 if (!g_allocator_dump_name_allowlist_for_testing) {
380 return kAllocatorDumpNameAllowlist.contains(stripped_str);
381 } else {
382 return IsNameInList(stripped_str.c_str(),
383 g_allocator_dump_name_allowlist_for_testing);
384 }
385 }
386
SetDumpProviderAllowlistForTesting(const char * const * list)387 void SetDumpProviderAllowlistForTesting(const char* const* list) {
388 g_dump_provider_allowlist_for_testing = list;
389 }
390
SetAllocatorDumpNameAllowlistForTesting(const char * const * list)391 void SetAllocatorDumpNameAllowlistForTesting(const char* const* list) {
392 g_allocator_dump_name_allowlist_for_testing = list;
393 }
394
395 } // namespace trace_event
396 } // namespace base
397