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:
Alexander Potapenko 2012-07-06 13:24:28 +00:00
parent 89f9270366
commit dc211a8db4
1 changed files with 26 additions and 16 deletions

View File

@ -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();
}
}
}