forked from OSchip/llvm-project
Fix http://code.google.com/p/address-sanitizer/issues/detail?id=87 by making sure we replace the default CFAllocator only after __CFInitialize has been called.
llvm-svn: 159749
This commit is contained in:
parent
38b1ec4317
commit
25b567dd0d
|
@ -295,8 +295,6 @@ INTERCEPTOR(void, dispatch_async_f, dispatch_queue_t dq, void *ctxt,
|
|||
asan_dispatch_call_block_and_release);
|
||||
}
|
||||
|
||||
DECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr)
|
||||
|
||||
INTERCEPTOR(void, dispatch_sync_f, dispatch_queue_t dq, void *ctxt,
|
||||
dispatch_function_t func) {
|
||||
GET_STACK_TRACE_HERE(kStackTraceMax);
|
||||
|
@ -428,6 +426,12 @@ INTERCEPTOR(CFStringRef, CFStringCreateCopy, CFAllocatorRef alloc,
|
|||
}
|
||||
}
|
||||
|
||||
DECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr)
|
||||
|
||||
extern "C"
|
||||
void __CFInitialize();
|
||||
DECLARE_REAL_AND_INTERCEPTOR(void, __CFInitialize)
|
||||
|
||||
namespace __asan {
|
||||
|
||||
void InitializeMacInterceptors() {
|
||||
|
@ -453,6 +457,9 @@ void InitializeMacInterceptors() {
|
|||
// Some of the library functions call free() directly, so we have to
|
||||
// intercept it.
|
||||
CHECK(INTERCEPT_FUNCTION(free));
|
||||
if (FLAG_replace_cfallocator) {
|
||||
CHECK(INTERCEPT_FUNCTION(__CFInitialize));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace __asan
|
||||
|
|
|
@ -78,6 +78,21 @@ INTERCEPTOR(void, free, void *ptr) {
|
|||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
// crash the program. Instead we wait for the allocator to initialize and jump
|
||||
// in just after __CFInitialize(). Nobody is going to allocate memory using
|
||||
// CFAllocators before that, so we won't miss anything.
|
||||
//
|
||||
// See http://code.google.com/p/address-sanitizer/issues/detail?id=87
|
||||
// and http://opensource.apple.com/source/CF/CF-550.43/CFRuntime.c
|
||||
INTERCEPTOR(void, __CFInitialize) {
|
||||
CHECK(FLAG_replace_cfallocator);
|
||||
REAL(__CFInitialize)();
|
||||
if (cf_asan) CFAllocatorSetDefault(cf_asan);
|
||||
}
|
||||
|
||||
namespace {
|
||||
// TODO(glider): the mz_* functions should be united with the Linux wrappers,
|
||||
// as they are basically copied from there.
|
||||
|
@ -300,7 +315,7 @@ boolean_t mi_zone_locked(malloc_zone_t *zone) {
|
|||
|
||||
} // unnamed namespace
|
||||
|
||||
extern bool kCFUseCollectableAllocator; // is GC on?
|
||||
extern int __CFRuntimeClassTableSize;
|
||||
|
||||
namespace __asan {
|
||||
void ReplaceSystemMalloc() {
|
||||
|
@ -377,7 +392,11 @@ void ReplaceSystemMalloc() {
|
|||
/*deallocate*/ &cf_free,
|
||||
/*preferredSize*/ 0 };
|
||||
cf_asan = CFAllocatorCreate(kCFAllocatorUseContext, &asan_context);
|
||||
CFAllocatorSetDefault(cf_asan);
|
||||
// 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 (if
|
||||
// __CFRuntimeClassTableSize is initialized) install cf_asan right now.
|
||||
if (__CFRuntimeClassTableSize) CFAllocatorSetDefault(cf_asan);
|
||||
}
|
||||
}
|
||||
} // namespace __asan
|
||||
|
|
Loading…
Reference in New Issue