chromium/base/allocator/partition_alloc_support.cc

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/allocator/partition_alloc_support.h"

#include <array>
#include <cinttypes>
#include <cstdint>
#include <map>
#include <optional>
#include <string>
#include <string_view>

#include "base/allocator/partition_alloc_features.h"
#include "base/at_exit.h"
#include "base/check.h"
#include "base/containers/span.h"
#include "base/cpu.h"
#include "base/debug/dump_without_crashing.h"
#include "base/debug/stack_trace.h"
#include "base/debug/task_trace.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/immediate_crash.h"
#include "base/location.h"
#include "base/memory/post_delayed_memory_reduction_task.h"
#include "base/memory/raw_ptr_asan_service.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/pending_task.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/system/sys_info.h"
#include "base/task/single_thread_task_runner.h"
#include "base/thread_annotations.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/trace_event/base_tracing.h"
#include "build/build_config.h"
#include "partition_alloc/allocation_guard.h"
#include "partition_alloc/buildflags.h"
#include "partition_alloc/dangling_raw_ptr_checks.h"
#include "partition_alloc/memory_reclaimer.h"
#include "partition_alloc/page_allocator.h"
#include "partition_alloc/partition_alloc_base/debug/alias.h"
#include "partition_alloc/partition_alloc_base/threading/platform_thread.h"
#include "partition_alloc/partition_alloc_check.h"
#include "partition_alloc/partition_alloc_config.h"
#include "partition_alloc/partition_alloc_constants.h"
#include "partition_alloc/partition_lock.h"
#include "partition_alloc/partition_root.h"
#include "partition_alloc/pointers/instance_tracer.h"
#include "partition_alloc/pointers/raw_ptr.h"
#include "partition_alloc/shim/allocator_shim.h"
#include "partition_alloc/shim/allocator_shim_default_dispatch_to_partition_alloc.h"
#include "partition_alloc/stack/stack.h"
#include "partition_alloc/thread_cache.h"

#if BUILDFLAG(IS_ANDROID)
#include "base/system/sys_info.h"
#endif

#if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
#include "partition_alloc/memory_reclaimer.h"
#endif

#if BUILDFLAG(IS_ANDROID) && PA_BUILDFLAG(HAS_MEMORY_TAGGING)
#include <sys/system_properties.h>
#endif

namespace base::allocator {

namespace {

#if BUILDFLAG(IS_ANDROID) && PA_BUILDFLAG(HAS_MEMORY_TAGGING)
enum class BootloaderOverride {
  kDefault,
  kForceOn,
  kForceOff,
};

BootloaderOverride GetBootloaderOverride() {
  char bootloader_override_str[PROP_VALUE_MAX];
  __system_property_get(
      "persist.device_config.runtime_native_boot.bootloader_override",
      bootloader_override_str);

  if (strcmp(bootloader_override_str, "force_on") == 0) {
    return BootloaderOverride::kForceOn;
  }
  if (strcmp(bootloader_override_str, "force_off") == 0) {
    return BootloaderOverride::kForceOff;
  }
  return BootloaderOverride::kDefault;
}
#endif

// When under this experiment avoid running periodic purging or reclaim for the
// first minute after the first attempt. This is based on the insight that
// processes often don't live paste this minute.
static BASE_FEATURE(kDelayFirstPeriodicPAPurgeOrReclaim,
                    "DelayFirstPeriodicPAPurgeOrReclaim",
                    base::FEATURE_ENABLED_BY_DEFAULT);
constexpr base::TimeDelta kFirstPAPurgeOrReclaimDelay =;

// This is defined in content/public/common/content_switches.h, which is not
// accessible in ::base. They must be kept in sync.
namespace switches {
[[maybe_unused]] constexpr char kRendererProcess[] =;
constexpr char kZygoteProcess[] =;
}  // namespace switches

}  // namespace

namespace {

void RunThreadCachePeriodicPurge() {}

}  // namespace

// When enabled, disable the memory reclaimer in background.
BASE_FEATURE();

// When enabled, limit the time memory reclaimer may take, returning early when
// exceeded.
BASE_FEATURE();

// static
MemoryReclaimerSupport& MemoryReclaimerSupport::Instance() {}
MemoryReclaimerSupport::~MemoryReclaimerSupport() = default;

MemoryReclaimerSupport::MemoryReclaimerSupport() = default;

void MemoryReclaimerSupport::Start(scoped_refptr<TaskRunner> task_runner) {}

void MemoryReclaimerSupport::SetForegrounded(bool in_foreground) {}

void MemoryReclaimerSupport::ResetForTesting() {}

void MemoryReclaimerSupport::Run() {}

// static
TimeDelta MemoryReclaimerSupport::GetInterval() {}

void MemoryReclaimerSupport::MaybeScheduleTask(TimeDelta delay) {}

void StartThreadCachePeriodicPurge() {}

void StartMemoryReclaimer(scoped_refptr<SequencedTaskRunner> task_runner) {}

std::map<std::string, std::string> ProposeSyntheticFinchTrials() {}

#if PA_BUILDFLAG(ENABLE_DANGLING_RAW_PTR_CHECKS)

namespace {

internal::PartitionLock g_stack_trace_buffer_lock;

constexpr size_t kDanglingPtrStackTraceSize =;

struct DanglingPointerFreeInfo {};
DanglingRawPtrBuffer;
DanglingRawPtrBuffer g_stack_trace_buffer GUARDED_BY();

void DanglingRawPtrDetected(uintptr_t id) {}

// From the traces recorded in |DanglingRawPtrDetected|, extract the one
// whose id match |id|. Return nullopt if not found.
std::optional<DanglingPointerFreeInfo> TakeDanglingPointerFreeInfo(
    uintptr_t id) {}

// Extract from the StackTrace output, the signature of the pertinent caller.
// This function is meant to be used only by Chromium developers, to list what
// are all the dangling raw_ptr occurrences in a table.
std::string ExtractDanglingPtrSignature(std::string stacktrace) {}

std::string ExtractDanglingPtrSignature(debug::TaskTrace task_trace) {}

std::string ExtractDanglingPtrSignature(
    std::optional<DanglingPointerFreeInfo> free_info,
    debug::StackTrace release_stack_trace,
    debug::TaskTrace release_task_trace) {}

bool operator==(const debug::TaskTrace& lhs, const debug::TaskTrace& rhs) {}

template <features::DanglingPtrMode dangling_pointer_mode,
          features::DanglingPtrType dangling_pointer_type>
void DanglingRawPtrReleased(uintptr_t id) {}

void CheckDanglingRawPtrBufferEmpty() {}

}  // namespace

void InstallDanglingRawPtrChecks() {}

// TODO(arthursonzogni): There might exist long lived dangling raw_ptr. If there
// is a dangling pointer, we should crash at some point. Consider providing an
// API to periodically check the buffer.

#else   // PA_BUILDFLAG(ENABLE_DANGLING_RAW_PTR_CHECKS)
void InstallDanglingRawPtrChecks() {}
#endif  // PA_BUILDFLAG(ENABLE_DANGLING_RAW_PTR_CHECKS)

void UnretainedDanglingRawPtrDetectedDumpWithoutCrashing(uintptr_t id) {}

void UnretainedDanglingRawPtrDetectedCrash(uintptr_t id) {}

void InstallUnretainedDanglingRawPtrChecks() {}

void ReconfigurePartitionForKnownProcess(const std::string& process_type) {}

PartitionAllocSupport* PartitionAllocSupport::Get() {}

PartitionAllocSupport::PartitionAllocSupport() = default;

void PartitionAllocSupport::ReconfigureForTests() {}

// static
bool PartitionAllocSupport::ShouldEnableMemoryTagging(
    const std::string& process_type) {}

// static
bool PartitionAllocSupport::ShouldEnableMemoryTaggingInRendererProcess() {}

// static
PartitionAllocSupport::BrpConfiguration
PartitionAllocSupport::GetBrpConfiguration(const std::string& process_type) {}

void PartitionAllocSupport::ReconfigureEarlyish(
    const std::string& process_type) {}

void PartitionAllocSupport::ReconfigureAfterZygoteFork(
    const std::string& process_type) {}

void PartitionAllocSupport::ReconfigureAfterFeatureListInit(
    const std::string& process_type,
    bool configure_dangling_pointer_detector) {}

void PartitionAllocSupport::ReconfigureAfterTaskRunnerInit(
    const std::string& process_type) {}

void PartitionAllocSupport::OnForegrounded(bool has_main_frame) {}

void PartitionAllocSupport::OnBackgrounded() {}

#if PA_BUILDFLAG(ENABLE_DANGLING_RAW_PTR_CHECKS)
std::string PartitionAllocSupport::ExtractDanglingPtrSignatureForTests(
    std::string stacktrace) {}
#endif

}  // namespace base::allocator