Hi everyone, (my apologies to those who've seen this email in the Google-only mailing list) The following program: ==================================== $ cat t.mm #import <Foundation/Foundation.h> int main() { #ifdef REPLACE CFAllocatorSetDefault(kCFAllocatorMallocZone); #endif NSURL *base = [[NSURL alloc] initWithString:@"file://localhost/Users/glider/Library/"]; NSURL *u = [[NSURL alloc] initWithString:@"Saved Application State" relativeToURL:base]; return 0; } ==================================== behaves incorrectly if CFAllocatorSetDefault is called: $ clang++ t.mm -o t -DREPLACE -framework Foundation -g && ./t t(47457) malloc: *** error for object 0x10ba14348: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug Abort trap: 6 This happens because _CFRuntimeCreateInstance (which is called from CFURLAlloc) checks whether the supplied allocator is kCFAllocatorSystemDefault and, if it is not, stores the allocator reference at the beginning of the allocated memory and returns the pointer to the allocated memory plus sizeof(CFAllocatorRef). See http://www.opensource.apple.com/source/CF/CF-550/CFRuntime.c for the reference. When the object is destroyed, nobody actually checks whether the pointer was skewed and corrects it: Breakpoint 1, 0x00007fff8f4e86c0 in malloc_error_break () (gdb) bt #0 0x00007fff8f4e86c0 in malloc_error_break () #1 0x00007fff8f4e8805 in free () #2 0x00007fff9375ed53 in object_dispose () #3 0x00007fff8e295086 in -[NSObject dealloc] () #4 0x00007fff8e854d4f in -[NSURL(NSURL) initWithString:relativeToURL:] () #5 0x0000000100000ded in main () at t.mm:36 To the best of my knowledge, _CFRelease (see CFRuntime.c again) is the only function that checks for the presence of the allocator reference at the beginning of the memory block, but it isn't called while destroying the object. My two questions are: 1. Is this correct that kCFAllocatorSystemDefault, not kCFAllocatorDefault (i.e. NULL), is treated specially? IIUC most of the time the libraries just pass NULL as the allocator. 2. How do I work around this? Looking for a CFAllocator pointer before each freed block within free() sounds lame (albeit efficient). Interposing _CFRuntimeCreateInstance with my own implementation that doesn't do dirty pointer tricks may be more correct, but it's too easy to break down next time CFRuntime.c changes. TIA, Alexander Potapenko Software Engineer Google Moscow _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-dev mailing list (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/darwin-dev/site_archiver%40lists.app... This email sent to site_archiver@lists.apple.com