partition_alloc_hooks.h 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // Copyright (c) 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_HOOKS_H_
  5. #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_HOOKS_H_
  6. #include <atomic>
  7. #include <cstddef>
  8. #include "base/allocator/partition_allocator/partition_alloc_base/component_export.h"
  9. namespace partition_alloc {
  10. // PartitionAlloc supports setting hooks to observe allocations/frees as they
  11. // occur as well as 'override' hooks that allow overriding those operations.
  12. class PA_COMPONENT_EXPORT(PARTITION_ALLOC) PartitionAllocHooks {
  13. public:
  14. // Log allocation and free events.
  15. typedef void AllocationObserverHook(void* address,
  16. size_t size,
  17. const char* type_name);
  18. typedef void FreeObserverHook(void* address);
  19. // If it returns true, the allocation has been overridden with the pointer in
  20. // *out.
  21. typedef bool AllocationOverrideHook(void** out,
  22. unsigned int flags,
  23. size_t size,
  24. const char* type_name);
  25. // If it returns true, then the allocation was overridden and has been freed.
  26. typedef bool FreeOverrideHook(void* address);
  27. // If it returns true, the underlying allocation is overridden and *out holds
  28. // the size of the underlying allocation.
  29. typedef bool ReallocOverrideHook(size_t* out, void* address);
  30. // To unhook, call Set*Hooks with nullptrs.
  31. static void SetObserverHooks(AllocationObserverHook* alloc_hook,
  32. FreeObserverHook* free_hook);
  33. static void SetOverrideHooks(AllocationOverrideHook* alloc_hook,
  34. FreeOverrideHook* free_hook,
  35. ReallocOverrideHook realloc_hook);
  36. // Helper method to check whether hooks are enabled. This is an optimization
  37. // so that if a function needs to call observer and override hooks in two
  38. // different places this value can be cached and only loaded once.
  39. static bool AreHooksEnabled() {
  40. return hooks_enabled_.load(std::memory_order_relaxed);
  41. }
  42. static void AllocationObserverHookIfEnabled(void* address,
  43. size_t size,
  44. const char* type_name);
  45. static bool AllocationOverrideHookIfEnabled(void** out,
  46. unsigned int flags,
  47. size_t size,
  48. const char* type_name);
  49. static void FreeObserverHookIfEnabled(void* address);
  50. static bool FreeOverrideHookIfEnabled(void* address);
  51. static void ReallocObserverHookIfEnabled(void* old_address,
  52. void* new_address,
  53. size_t size,
  54. const char* type_name);
  55. static bool ReallocOverrideHookIfEnabled(size_t* out, void* address);
  56. private:
  57. // Single bool that is used to indicate whether observer or allocation hooks
  58. // are set to reduce the numbers of loads required to check whether hooking is
  59. // enabled.
  60. static std::atomic<bool> hooks_enabled_;
  61. // Lock used to synchronize Set*Hooks calls.
  62. static std::atomic<AllocationObserverHook*> allocation_observer_hook_;
  63. static std::atomic<FreeObserverHook*> free_observer_hook_;
  64. static std::atomic<AllocationOverrideHook*> allocation_override_hook_;
  65. static std::atomic<FreeOverrideHook*> free_override_hook_;
  66. static std::atomic<ReallocOverrideHook*> realloc_override_hook_;
  67. };
  68. } // namespace partition_alloc
  69. #endif // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_HOOKS_H_