forked from OSchip/llvm-project
Because CFAllocatorCreate() should also be called after __CFInitialize() on Lion,
do so by factoring the CFAllocator logic into ReplaceCFAllocator(), which is called from either the __CFInitialize wrapper or __asan_init(), depending on which of them is called later. llvm-svn: 159822
This commit is contained in:
parent
89f9270366
commit
dc211a8db4
|
@ -35,6 +35,7 @@ using namespace __asan; // NOLINT
|
|||
// TODO(glider): do we need both zones?
|
||||
static malloc_zone_t *system_malloc_zone = 0;
|
||||
static malloc_zone_t *system_purgeable_zone = 0;
|
||||
static malloc_zone_t asan_zone;
|
||||
CFAllocatorRef cf_asan = 0;
|
||||
|
||||
// The free() implementation provided by OS X calls malloc_zone_from_ptr()
|
||||
|
@ -80,6 +81,10 @@ INTERCEPTOR(void, free, void *ptr) {
|
|||
}
|
||||
}
|
||||
|
||||
namespace __asan {
|
||||
void ReplaceCFAllocator();
|
||||
}
|
||||
|
||||
// We can't always replace the default CFAllocator with cf_asan right in
|
||||
// ReplaceSystemMalloc(), because it is sometimes called before
|
||||
// __CFInitialize(), when the default allocator is invalid and replacing it may
|
||||
|
@ -91,11 +96,13 @@ INTERCEPTOR(void, free, void *ptr) {
|
|||
// and http://opensource.apple.com/source/CF/CF-550.43/CFRuntime.c
|
||||
INTERCEPTOR(void, __CFInitialize) {
|
||||
CHECK(FLAG_replace_cfallocator);
|
||||
CHECK(asan_inited);
|
||||
REAL(__CFInitialize)();
|
||||
if (cf_asan) CFAllocatorSetDefault(cf_asan);
|
||||
ReplaceCFAllocator();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// TODO(glider): the mz_* functions should be united with the Linux wrappers,
|
||||
// as they are basically copied from there.
|
||||
size_t mz_size(malloc_zone_t* zone, const void* ptr) {
|
||||
|
@ -320,6 +327,19 @@ boolean_t mi_zone_locked(malloc_zone_t *zone) {
|
|||
extern int __CFRuntimeClassTableSize;
|
||||
|
||||
namespace __asan {
|
||||
void ReplaceCFAllocator() {
|
||||
static CFAllocatorContext asan_context = {
|
||||
/*version*/ 0, /*info*/ &asan_zone,
|
||||
/*retain*/ 0, /*release*/ 0,
|
||||
/*copyDescription*/0,
|
||||
/*allocate*/ &cf_malloc,
|
||||
/*reallocate*/ &cf_realloc,
|
||||
/*deallocate*/ &cf_free,
|
||||
/*preferredSize*/ 0 };
|
||||
cf_asan = CFAllocatorCreate(kCFAllocatorUseContext, &asan_context);
|
||||
CFAllocatorSetDefault(cf_asan);
|
||||
}
|
||||
|
||||
void ReplaceSystemMalloc() {
|
||||
static malloc_introspection_t asan_introspection;
|
||||
// Ok to use internal_memset, these places are not performance-critical.
|
||||
|
@ -333,7 +353,6 @@ void ReplaceSystemMalloc() {
|
|||
asan_introspection.force_lock = &mi_force_lock;
|
||||
asan_introspection.force_unlock = &mi_force_unlock;
|
||||
|
||||
static malloc_zone_t asan_zone;
|
||||
internal_memset(&asan_zone, 0, sizeof(malloc_zone_t));
|
||||
|
||||
// Start with a version 4 zone which is used for OS X 10.4 and 10.5.
|
||||
|
@ -385,23 +404,14 @@ void ReplaceSystemMalloc() {
|
|||
CHECK(malloc_default_zone() == &asan_zone);
|
||||
|
||||
if (FLAG_replace_cfallocator) {
|
||||
static CFAllocatorContext asan_context =
|
||||
{ /*version*/ 0, /*info*/ &asan_zone,
|
||||
/*retain*/ 0, /*release*/ 0,
|
||||
/*copyDescription*/0,
|
||||
/*allocate*/ &cf_malloc,
|
||||
/*reallocate*/ &cf_realloc,
|
||||
/*deallocate*/ &cf_free,
|
||||
/*preferredSize*/ 0 };
|
||||
cf_asan = CFAllocatorCreate(kCFAllocatorUseContext, &asan_context);
|
||||
// If __CFInitialize() hasn't been called yet, cf_asan will be installed
|
||||
// as the default allocator after __CFInitialize() finishes (see the
|
||||
// interceptor for __CFInitialize() above). Otherwise install cf_asan right
|
||||
// now. On both Snow Leopard and Lion __CFInitialize() calls
|
||||
// If __CFInitialize() hasn't been called yet, cf_asan will be created and
|
||||
// installed as the default allocator after __CFInitialize() finishes (see
|
||||
// the interceptor for __CFInitialize() above). Otherwise install cf_asan
|
||||
// right now. On both Snow Leopard and Lion __CFInitialize() calls
|
||||
// __CFAllocatorInitialize(), which initializes the _base._cfisa field of
|
||||
// the default allocators we check here.
|
||||
if (((CFRuntimeBase*)kCFAllocatorSystemDefault)->_cfisa) {
|
||||
CFAllocatorSetDefault(cf_asan);
|
||||
ReplaceCFAllocator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue