blob: 524bc705ffd017787901ffc2a411467901ecd5a0 [file] [log] [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
#pragma allow_unsafe_buffers
#endif
#include "base/trace_event/memory_infra_background_allowlist.h"
#include <string.h>
#include <string>
#include <string_view>
#include "base/containers/fixed_flat_set.h"
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "partition_alloc/partition_alloc_buildflags.h"
#include "third_party/abseil-cpp/absl/strings/ascii.h"
#if BUILDFLAG(IS_ANDROID)
#include "base/android/meminfo_dump_provider.h"
#endif
namespace base {
namespace trace_event {
namespace {
// The names of dump providers allowed to perform background tracing. Dump
// providers can be added here only if the background mode dump has very
// little processor and memory overhead.
// TODO(ssid): Some dump providers do not create ownership edges on background
// dump. So, the effective size will not be correct.
constexpr auto kDumpProviderAllowlist =
base::MakeFixedFlatSet<std::string_view>({
// clang-format off
#if BUILDFLAG(IS_ANDROID)
base::android::MeminfoDumpProvider::kDumpProviderName,
"android::ResourceManagerImpl",
#endif
"AutocompleteController",
"AXPlatformNode",
"BlinkGC",
"BlinkObjectCounters",
"BlobStorageContext",
"Canvas",
"ClientDiscardableSharedMemoryManager",
#if BUILDFLAG(IS_MAC)
"CommandBuffer",
#endif
"ContextProviderCommandBuffer",
"DOMStorage",
"DevTools",
"DiscardableSharedMemoryManager",
"DownloadService",
"ExtensionFunctions",
"FontCaches",
"FrameEvictionManager",
"GrShaderCache",
"HistoryReport",
"cc::ResourcePool",
"gpu::BufferManager",
"gpu::RenderbufferManager",
"gpu::ServiceDiscardableManager",
"gpu::ServiceTransferCache",
"gpu::SharedImageStub",
"gpu::TextureManager",
"hibernated_canvas",
"vulkan",
"IPCChannel",
"InMemoryURLIndex",
"IndexedDBBackingStore",
"IndexedDBFactoryImpl",
"JavaHeap",
"LevelDB",
"LeveldbValueStore",
"LocalStorage",
"MadvFreeDiscardableMemoryAllocator",
"Malloc",
"ManualFillingCache",
"MemoryCache",
"MojoHandleTable",
"MojoLevelDB",
"MojoMessages",
"PartitionAlloc",
"PartitionAlloc.AddressSpace",
"ProcessMemoryMetrics",
"SharedContextState",
"SharedImageManager",
"SharedMemoryTracker",
"Skia",
"Sql",
"TabRestoreServiceHelper",
"TextureOwner"
"URLRequestContext",
"V8Isolate",
"WebMediaPlayer_MainThread",
"WebMediaPlayer_MediaThread",
// clang-format on
});
// A list of string names that are allowed for the memory allocator dumps in
// background mode.
constexpr auto kAllocatorDumpNameAllowlist =
base::MakeFixedFlatSet<std::string_view>({
// clang-format off
// Some of the blink values vary based on compile time flags. The
// compile time flags are not in base, so all are listed here.
#if BUILDFLAG(IS_ANDROID)
base::android::MeminfoDumpProvider::kDumpName,
#endif
"accessibility/ax_platform_node",
"blink_gc/main/allocated_objects",
"blink_gc/main/heap",
"blink_gc/workers/heap/worker_0x?",
"blink_gc/workers/worker_0x?/heap",
"blink_gc/workers/worker_0x?/allocated_objects",
"blink_objects/AdSubframe",
"blink_objects/ArrayBufferContents",
"blink_objects/AudioHandler",
"blink_objects/AudioWorkletProcessor",
"blink_objects/ContextLifecycleStateObserver",
"blink_objects/DetachedScriptState",
"blink_objects/Document",
"blink_objects/Frame",
"blink_objects/JSEventListener",
"blink_objects/LayoutObject",
"blink_objects/MediaKeySession",
"blink_objects/MediaKeys",
"blink_objects/Node",
"blink_objects/Resource",
"blink_objects/RTCPeerConnection",
"blink_objects/ScriptPromise",
"blink_objects/V8PerContextData",
"blink_objects/WorkerGlobalScope",
"blink_objects/UACSSResource",
"blink_objects/ResourceFetcher",
"canvas/hibernated",
"canvas/ResourceProvider/SkSurface",
"canvas/ResourceProvider/SkSurface/0x?",
"cc/tile_memory/provider_0x?",
"components/download/controller_0x?",
"devtools/file_watcher_0x?",
"discardable",
"discardable/madv_free_allocated",
"discardable/child_0x?",
"extensions/functions",
"extensions/value_store/Extensions.Database.Open.OriginManagedConfiguration/0x?",
"extensions/value_store/Extensions.Database.Open.Rules/0x?",
"extensions/value_store/Extensions.Database.Open.Scripts/0x?",
"extensions/value_store/Extensions.Database.Open.Settings/0x?",
"extensions/value_store/Extensions.Database.Open.State/0x?",
"extensions/value_store/Extensions.Database.Open.WebAppsLockScreen/0x?",
"extensions/value_store/Extensions.Database.Open/0x?",
"extensions/value_store/Extensions.Database.Restore/0x?",
"extensions/value_store/Extensions.Database.Value.Restore/0x?",
"font_caches/font_platform_data_cache",
"font_caches/shape_caches",
"frame_evictor",
"gpu/command_buffer_memory/buffer_0x?",
"gpu/discardable_cache/cache_0x?",
"gpu/discardable_cache/cache_0x?/avg_image_size",
"gpu/gl/buffers/context_group_0x?",
"gpu/gl/renderbuffers/context_group_0x?",
"gpu/gl/textures/context_group_0x?",
"gpu/gr_shader_cache/cache_0x?",
"gpu/mapped_memory/manager_0x?",
"gpu/shared_images",
"gpu/media_texture_owner_?",
"gpu/transfer_buffer_memory/buffer_0x?",
"gpu/transfer_cache/cache_0x?",
"gpu/transfer_cache/cache_0x?/avg_image_size",
"gpu/vulkan/vma_allocator_0x?",
"history/delta_file_service/leveldb_0x?",
"history/usage_reports_buffer/leveldb_0x?",
#if BUILDFLAG(IS_MAC)
"ioaccelerator",
"iosurface",
#endif
"java_heap",
"java_heap/allocated_objects",
"leveldatabase",
"leveldatabase/block_cache/browser",
"leveldatabase/block_cache/in_memory",
"leveldatabase/block_cache/unified",
"leveldatabase/block_cache/web",
"leveldatabase/db_0x?",
"leveldatabase/db_0x?/block_cache",
"leveldatabase/memenv_0x?",
"malloc",
"malloc/allocated_objects",
#if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
"malloc/extreme_lud",
#endif
"malloc/metadata_fragmentation_caches",
#if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
"malloc/partitions",
"malloc/partitions/allocator",
"malloc/partitions/allocator/scheduler_loop_quarantine",
"malloc/partitions/allocator/thread_cache",
"malloc/partitions/allocator/thread_cache/main_thread",
"malloc/partitions/aligned",
"malloc/partitions/original",
"malloc/partitions/nonscannable",
"malloc/partitions/nonquarantinable",
"malloc/sys_malloc",
"malloc/win_heap",
#endif // PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
"media/webmediaplayer/audio/player_0x?",
"media/webmediaplayer/data_source/player_0x?",
"media/webmediaplayer/demuxer/player_0x?",
"media/webmediaplayer/video/player_0x?",
"media/webmediaplayer/player_0x?",
"mojo",
"mojo/data_pipe_consumer",
"mojo/data_pipe_producer",
"mojo/invitation",
"mojo/messages",
"mojo/message_pipe",
"mojo/platform_handle",
"mojo/queued_ipc_channel_message/0x?",
"mojo/shared_buffer",
"mojo/unknown",
"mojo/watcher",
"omnibox/autocomplete_controller/0x?",
"omnibox/in_memory_url_index/0x?",
"passwords/manual_filling_controller/0x?",
"web_cache/Image_resources",
"web_cache/CSS stylesheet_resources",
"web_cache/Script_resources",
"web_cache/XSL stylesheet_resources",
"web_cache/Font_resources",
"web_cache/Code_cache",
"web_cache/Encoded_size_duplicated_in_data_urls",
"web_cache/Other_resources",
"partition_alloc/allocated_objects",
"partition_alloc/address_space",
"partition_alloc/partitions",
"partition_alloc/partitions/array_buffer",
"partition_alloc/partitions/buffer",
"partition_alloc/partitions/fast_malloc",
#if !PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
"partition_alloc/partitions/fast_malloc/thread_cache",
"partition_alloc/partitions/fast_malloc/thread_cache/main_thread",
#endif
"partition_alloc/partitions/layout",
"skia/gpu_resources/context_0x?",
"skia/sk_glyph_cache",
"skia/sk_resource_cache",
"sqlite",
"ui/resource_manager_0x?/default_resource/0x?",
"ui/resource_manager_0x?/tinted_resource",
"site_storage/blob_storage/0x?",
"v8/main/code_stats",
"v8/main/contexts/detached_context",
"v8/main/contexts/native_context",
"v8/main/global_handles",
"v8/main/heap/code_space",
"v8/main/heap/code_stats",
"v8/main/heap/code_large_object_space",
"v8/main/heap/large_object_space",
"v8/main/heap/map_space",
"v8/main/heap/new_large_object_space",
"v8/main/heap/new_space",
"v8/main/heap/old_space",
"v8/main/heap/read_only_space",
"v8/main/heap/shared_large_object_space",
"v8/main/heap/shared_space",
"v8/main/heap/shared_trusted_large_object_space",
"v8/main/heap/shared_trusted_space",
"v8/main/heap/trusted_space",
"v8/main/heap/trusted_large_object_space",
"v8/main/malloc",
"v8/main/zapped_for_debug",
"v8/utility/code_stats",
"v8/utility/contexts/detached_context",
"v8/utility/contexts/native_context",
"v8/utility/global_handles",
"v8/utility/heap/code_space",
"v8/utility/heap/code_large_object_space",
"v8/utility/heap/large_object_space",
"v8/utility/heap/map_space",
"v8/utility/heap/new_large_object_space",
"v8/utility/heap/new_space",
"v8/utility/heap/old_space",
"v8/utility/heap/read_only_space",
"v8/utility/heap/shared_large_object_space",
"v8/utility/heap/shared_space",
"v8/utility/heap/shared_trusted_large_object_space",
"v8/utility/heap/shared_trusted_space",
"v8/utility/heap/trusted_space",
"v8/utility/heap/trusted_large_object_space",
"v8/utility/malloc",
"v8/utility/zapped_for_debug",
"v8/workers/code_stats/isolate_0x?",
"v8/workers/contexts/detached_context/isolate_0x?",
"v8/workers/contexts/native_context/isolate_0x?",
"v8/workers/global_handles/isolate_0x?",
"v8/workers/heap/code_space/isolate_0x?",
"v8/workers/heap/code_large_object_space/isolate_0x?",
"v8/workers/heap/large_object_space/isolate_0x?",
"v8/workers/heap/map_space/isolate_0x?",
"v8/workers/heap/new_large_object_space/isolate_0x?",
"v8/workers/heap/new_space/isolate_0x?",
"v8/workers/heap/old_space/isolate_0x?",
"v8/workers/heap/read_only_space/isolate_0x?",
"v8/workers/heap/shared_large_object_space/isolate_0x?",
"v8/workers/heap/shared_space/isolate_0x?",
"v8/workers/heap/shared_trusted_large_object_space/isolate_0x?",
"v8/workers/heap/shared_trusted_space/isolate_0x?",
"v8/workers/heap/trusted_space/isolate_0x?",
"v8/workers/heap/trusted_large_object_space/isolate_0x?",
"v8/workers/malloc/isolate_0x?",
"v8/workers/zapped_for_debug/isolate_0x?",
"site_storage/index_db/db_0x?",
"site_storage/index_db/memenv_0x?",
"site_storage/index_db/in_flight_0x?",
"site_storage/local_storage/0x?/cache_size",
"site_storage/localstorage/0x?/cache_size",
"site_storage/localstorage/0x?/leveldb",
"site_storage/session_storage/0x?",
"site_storage/session_storage/0x?/cache_size",
"tab_restore/service_helper_0x?/entries",
"tab_restore/service_helper_0x?/entries/group_0x?",
"tab_restore/service_helper_0x?/entries/tab_0x?",
"tab_restore/service_helper_0x?/entries/window_0x?",
"tracing/heap_profiler_blink_gc/AllocationRegister",
"tracing/heap_profiler_malloc/AllocationRegister",
"tracing/heap_profiler_partition_alloc/AllocationRegister",
// clang-format on
});
const char* const* g_dump_provider_allowlist_for_testing = nullptr;
const char* const* g_allocator_dump_name_allowlist_for_testing = nullptr;
bool IsNameInList(const char* name, const char* const* list) {
for (size_t i = 0; list[i] != nullptr; ++i) {
if (strcmp(name, list[i]) == 0)
return true;
}
return false;
}
} // namespace
bool IsMemoryDumpProviderInAllowlist(const char* mdp_name) {
if (!g_dump_provider_allowlist_for_testing) {
return kDumpProviderAllowlist.contains(mdp_name);
} else {
return IsNameInList(mdp_name, g_dump_provider_allowlist_for_testing);
}
}
bool IsMemoryAllocatorDumpNameInAllowlist(const std::string& name) {
// Global dumps that are of hex digits are all allowed for background use.
if (base::StartsWith(name, "global/", CompareCase::SENSITIVE)) {
for (size_t i = strlen("global/"); i < name.size(); i++)
if (!base::IsHexDigit(name[i]))
return false;
return true;
}
if (base::StartsWith(name, "shared_memory/", CompareCase::SENSITIVE)) {
for (size_t i = strlen("shared_memory/"); i < name.size(); i++)
if (!base::IsHexDigit(name[i]))
return false;
return true;
}
// Remove special characters, numbers (including hexadecimal which are marked
// by '0x') from the given string.
const size_t length = name.size();
std::string stripped_str;
stripped_str.reserve(length);
bool parsing_hex = false;
for (size_t i = 0; i < length; ++i) {
if (parsing_hex &&
absl::ascii_isxdigit(static_cast<unsigned char>(name[i]))) {
continue;
}
parsing_hex = false;
if (i + 1 < length && name[i] == '0' && name[i + 1] == 'x') {
parsing_hex = true;
stripped_str.append("0x?");
++i;
} else {
stripped_str.push_back(name[i]);
}
}
if (!g_allocator_dump_name_allowlist_for_testing) {
return kAllocatorDumpNameAllowlist.contains(stripped_str);
} else {
return IsNameInList(stripped_str.c_str(),
g_allocator_dump_name_allowlist_for_testing);
}
}
void SetDumpProviderAllowlistForTesting(const char* const* list) {
g_dump_provider_allowlist_for_testing = list;
}
void SetAllocatorDumpNameAllowlistForTesting(const char* const* list) {
g_allocator_dump_name_allowlist_for_testing = list;
}
} // namespace trace_event
} // namespace base