Commit 0b16177e authored by Avi Drissman's avatar Avi Drissman Committed by Commit Bot

Update Mac memory code references

The Mac malloc interceptor relies on internals of macOS.
Update those internals and links to the 10.15 versions.

This relands 994f22b5
with a fix for profiling_client.cc which correctly only
includes a Mac file header on the Mac.

Bug: none
Change-Id: I8132dc1ffeeb0c6b65edb80cc729bcb4836f2121
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2377983Reviewed-by: default avatarErik Chen <erikchen@chromium.org>
Reviewed-by: default avatarMark Mentovai <mark@chromium.org>
Commit-Queue: Avi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#802429}
parent 5e950b29
......@@ -77,13 +77,14 @@ void DeprotectMallocZone(ChromeMallocZone* default_zone,
MACH_CHECK(result == KERN_SUCCESS, result) << "vm_region_64";
// The kernel always returns a null object for VM_REGION_BASIC_INFO_64, but
// balance it with a deallocate in case this ever changes. See 10.9.2
// xnu-2422.90.20/osfmk/vm/vm_map.c vm_map_region.
// balance it with a deallocate in case this ever changes. See
// the VM_REGION_BASIC_INFO_64 case in vm_map_region() in 10.15's
// https://opensource.apple.com/source/xnu/xnu-6153.11.26/osfmk/vm/vm_map.c .
mach_port_deallocate(mach_task_self(), unused);
// Does the region fully enclose the zone pointers? Possibly unwarranted
// simplification used: using the size of a full version 8 malloc zone rather
// than the actual smaller size if the passed-in zone is not version 8.
// simplification used: using the size of a full version 10 malloc zone rather
// than the actual smaller size if the passed-in zone is not version 10.
CHECK(*reprotection_start <= reinterpret_cast<vm_address_t>(default_zone));
vm_size_t zone_offset = reinterpret_cast<vm_address_t>(default_zone) -
reinterpret_cast<vm_address_t>(*reprotection_start);
......@@ -147,8 +148,8 @@ void* oom_killer_memalign(struct _malloc_zone_t* zone,
size_t size) {
void* result = g_old_zone.memalign(zone, alignment, size);
// Only die if posix_memalign would have returned ENOMEM, since there are
// other reasons why NULL might be returned (see
// http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ).
// other reasons why null might be returned. See posix_memalign() in 10.15's
// https://opensource.apple.com/source/libmalloc/libmalloc-283/src/malloc.c .
if (!result && size && alignment >= sizeof(void*) &&
base::bits::IsPowerOfTwo(alignment)) {
TerminateBecauseOutOfMemory(size);
......@@ -197,8 +198,8 @@ void* oom_killer_memalign_purgeable(struct _malloc_zone_t* zone,
size_t size) {
void* result = g_old_purgeable_zone.memalign(zone, alignment, size);
// Only die if posix_memalign would have returned ENOMEM, since there are
// other reasons why NULL might be returned (see
// http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ).
// other reasons why null might be returned. See posix_memalign() in 10.15's
// https://opensource.apple.com/source/libmalloc/libmalloc-283/src/malloc.c .
if (!result && size && alignment >= sizeof(void*) &&
base::bits::IsPowerOfTwo(alignment)) {
TerminateBecauseOutOfMemory(size);
......@@ -363,11 +364,11 @@ void InterceptAllocationsMac() {
// === C malloc/calloc/valloc/realloc/posix_memalign ===
// This approach is not perfect, as requests for amounts of memory larger than
// MALLOC_ABSOLUTE_MAX_SIZE (currently SIZE_T_MAX - (2 * PAGE_SIZE)) will
// still fail with a NULL rather than dying (see
// http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c for details).
// Unfortunately, it's the best we can do. Also note that this does not affect
// allocations from non-default zones.
// MALLOC_ABSOLUTE_MAX_SIZE (currently SIZE_T_MAX - (2 * PAGE_SIZE)) will still
// fail with a NULL rather than dying (see malloc_zone_malloc() in
// https://opensource.apple.com/source/libmalloc/libmalloc-283/src/malloc.c for
// details). Unfortunately, it's the best we can do. Also note that this does
// not affect allocations from non-default zones.
#if !defined(ADDRESS_SANITIZER)
// Don't do anything special on OOM for the malloc zones replaced by
......
......@@ -40,6 +40,10 @@ void StoreZoneFunctions(const ChromeMallocZone* zone,
functions->free_definite_size = zone->free_definite_size;
}
// Note that zone version 8 introduced a pressure relief callback, and version
// 10 introduced a claimed address callback, but neither are allocation or
// deallocation callbacks and so aren't important to intercept.
functions->context = zone;
}
......
......@@ -8,7 +8,6 @@
#include <unordered_set>
#include <vector>
#include "base/allocator/allocator_interception_mac.h"
#include "base/bind.h"
#include "base/debug/stack_trace.h"
#include "base/lazy_instance.h"
......@@ -25,6 +24,10 @@
#include "base/trace_event/cfi_backtrace_android.h"
#endif
#if defined(OS_APPLE)
#include "base/allocator/allocator_interception_mac.h"
#endif
namespace heap_profiling {
ProfilingClient::ProfilingClient() = default;
......
......@@ -7,11 +7,12 @@ License: Apple Public Source License 2.0
Four files are excerpted here:
malloc.h from:
http://www.opensource.apple.com/source/Libc/Libc-763.11/include/malloc/malloc.h
https://opensource.apple.com/source/libmalloc/libmalloc-283/include/malloc/malloc.h
Modifications:
- Modified #ifdef guards.
- Removed everything but the definition of malloc_zone_t.
- Added a header for the definition of boolean_t.
- Renamed _malloc_zone_t to ChromeMallocZone to avoid possible name conflicts.
CFRuntime.h from:
......
......@@ -24,6 +24,8 @@
#ifndef THIRD_PARTY_APPLE_APSL_MALLOC_H_
#define THIRD_PARTY_APPLE_APSL_MALLOC_H_
#include <mach/boolean.h>
typedef struct _ChromeMallocZone {
/* Only zone implementors should depend on the layout of this structure;
Regular callers should use the access functions below */
......@@ -53,6 +55,13 @@ typedef struct _ChromeMallocZone {
/* Empty out caches in the face of memory pressure. The callback may be NULL. Present in version >= 8. */
size_t (*pressure_relief)(struct _malloc_zone_t *zone, size_t goal);
/*
* Checks whether an address might belong to the zone. May be NULL. Present in version >= 10.
* False positives are allowed (e.g. the pointer was freed, or it's in zone space that has
* not yet been allocated. False negatives are not allowed.
*/
boolean_t (*claimed_address)(struct _malloc_zone_t *zone, void *ptr);
} ChromeMallocZone;
#endif // THIRD_PARTY_APPLE_APSL_MALLOC_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment