Factor the common code out of cf_free and mz_free.

Introduce the mac_ignore_invalid_free flag (0 by default) which makes both cf_free and mz_free ignore invalid free invocations and leak memory.

llvm-svn: 158885
This commit is contained in:
Alexander Potapenko 2012-06-21 01:01:20 +00:00
parent 4b3d2c801c
commit 1bde28b464
3 changed files with 12 additions and 26 deletions

View File

@ -148,6 +148,7 @@ extern uptr FLAG_malloc_context_size;
extern bool FLAG_replace_str;
extern bool FLAG_replace_intrin;
extern bool FLAG_replace_cfallocator;
extern bool FLAG_mac_ignore_invalid_free;
extern bool FLAG_fast_unwind;
extern bool FLAG_use_fake_stack;
extern uptr FLAG_max_malloc_fill_size;

View File

@ -149,8 +149,7 @@ void print_zone_for_ptr(void *ptr) {
}
}
// TODO(glider): the allocation callbacks need to be refactored.
void mz_free(malloc_zone_t *zone, void *ptr) {
void ALWAYS_INLINE free_common(void *context, void *ptr) {
if (!ptr) return;
malloc_zone_t *orig_zone = malloc_zone_from_ptr(ptr);
// For some reason Chromium calls mz_free() for pointers that belong to
@ -160,12 +159,12 @@ void mz_free(malloc_zone_t *zone, void *ptr) {
system_purgeable_zone->free(system_purgeable_zone, ptr);
return;
}
if (asan_mz_size(ptr)) {
if (!FLAG_mac_ignore_invalid_free || asan_mz_size(ptr)) {
GET_STACK_TRACE_HERE_FOR_FREE(ptr);
asan_free(ptr, &stack);
} else {
// Let us just leak this memory for now.
AsanPrintf("mz_free(%p) -- attempting to free unallocated memory.\n"
AsanPrintf("free_common(%p) -- attempting to free unallocated memory.\n"
"AddressSanitizer is ignoring this error on Mac OS now.\n",
ptr);
print_zone_for_ptr(ptr);
@ -175,29 +174,13 @@ void mz_free(malloc_zone_t *zone, void *ptr) {
}
}
// TODO(glider): the allocation callbacks need to be refactored.
void mz_free(malloc_zone_t *zone, void *ptr) {
free_common(zone, ptr);
}
void cf_free(void *ptr, void *info) {
if (!ptr) return;
malloc_zone_t *orig_zone = malloc_zone_from_ptr(ptr);
// For some reason Chromium calls mz_free() for pointers that belong to
// DefaultPurgeableMallocZone instead of asan_zone. We might want to
// fix this someday.
if (orig_zone == system_purgeable_zone) {
system_purgeable_zone->free(system_purgeable_zone, ptr);
return;
}
if (asan_mz_size(ptr)) {
GET_STACK_TRACE_HERE_FOR_FREE(ptr);
asan_free(ptr, &stack);
} else {
// Let us just leak this memory for now.
AsanPrintf("cf_free(%p) -- attempting to free unallocated memory.\n"
"AddressSanitizer is ignoring this error on Mac OS now.\n",
ptr);
print_zone_for_ptr(ptr);
GET_STACK_TRACE_HERE_FOR_FREE(ptr);
stack.PrintStack();
return;
}
free_common(info, ptr);
}
void *mz_realloc(malloc_zone_t *zone, void *ptr, size_t size) {

View File

@ -73,6 +73,7 @@ bool FLAG_symbolize = 0;
s64 FLAG_demangle = 1;
s64 FLAG_debug = 0;
bool FLAG_replace_cfallocator = 1; // Used on Mac only.
bool FLAG_mac_ignore_invalid_free = 0; // Used on Mac only.
bool FLAG_replace_str = 1;
bool FLAG_replace_intrin = 1;
bool FLAG_use_fake_stack = 1;
@ -458,6 +459,7 @@ static void ParseAsanOptions(const char *options) {
IntFlagValue(options, "demangle=", &FLAG_demangle);
IntFlagValue(options, "debug=", &FLAG_debug);
BoolFlagValue(options, "replace_cfallocator=", &FLAG_replace_cfallocator);
BoolFlagValue(options, "mac_ignore_invalid_free=", &FLAG_mac_ignore_invalid_free);
BoolFlagValue(options, "replace_str=", &FLAG_replace_str);
BoolFlagValue(options, "replace_intrin=", &FLAG_replace_intrin);
BoolFlagValue(options, "use_fake_stack=", &FLAG_use_fake_stack);