3

I have been hunting all over my code and can't find the source of this crash: I am trying to decode an object with an NSKeyedUnarchiver and it crashes on it every time and says:

*** __NSAutoreleaseFreedObject(): release of previously deallocated object (0x1008ad200) ignored
*** __NSAutoreleaseFreedObject(): release of previously deallocated object (0x1008ab200) ignored
*** __NSAutoreleaseFreedObject(): release of previously deallocated object (0x1008a8c00) ignored

Ha my bad the reason why initWithCoder was not getting called was it was having issues with the [super initWithCoder:]; This is still driving me crazy. I looked and the pointers and the NSData objects are what are going wrong:

    vertices = malloc(size_point3D * vertexCount);
    textureCoords = malloc(size_point2D * textureCount);
    normals = malloc(size_point3D * normalCount);
    faces = malloc(sizeof(GLuint) * faceCount);


    NSData *vertexData = [[NSData alloc] initWithData:[coder decodeObjectForKey:@"vertices"]];
    NSData *textureData = [[NSData alloc] initWithData:[coder decodeObjectForKey:@"textureCoords"]];
    NSData *normalData = [[NSData alloc] initWithData:[coder decodeObjectForKey:@"normals"]];
    NSData *faceData = [[NSData alloc] initWithData:[coder decodeObjectForKey:@"faces"]];


    memcpy(vertices, [vertexData bytes],  sizeof(point3D) * vertexCount);
    memcpy(textureCoords, [textureData bytes], sizeof(point2D) * textureCount);
    memcpy(normals, [normalData bytes], sizeof(point3D) * normalCount);
    memcpy(faces, [faceData bytes], sizeof(GLuint) * faceCount);

    [vertexData release];
    [textureData release];
    [normalData release];
    [faceData release];

I have tried retaining everything in this part (even the string) but it does not help.

Justin Meiners
  • 10,754
  • 6
  • 50
  • 92
  • Uh sure but its a pretty deep stack – Justin Meiners Sep 06 '10 at 04:05
  • It looks like you're redefining model. And is path an ivar? I think step 1 would be to figure out exactly which object is trying to get freed twice. Kinda tricky with so little code to go on. – taber Sep 06 '10 at 04:39
  • Well its a little confusing how it works and no I am not basicly when you load a model from a file it uses NSKeyedUnarchiver to decode it and copy the data into itself believe me this works when garbage collection is on and it even works on the iPhone. – Justin Meiners Sep 06 '10 at 04:41
  • What does your `initWithCoder:` look like? It seems like that would be where the bug is cropping up. Pretty good money this is not a bug in Cocoa. The reason a bug would happen under managed memory but not garbage collection is that garbage collection prevents you from releasing objects that are still referenced, which is what would cause this sort of error. – Chuck Sep 06 '10 at 04:42
  • I put a break point in there and it is crashing before that even gets called! – Justin Meiners Sep 06 '10 at 04:47
  • hmm, maybe try setting each obj you're releasing to nil after releasing to be sure another thread isn't still trying to access them. – taber Sep 06 '10 at 04:55
  • I tried something like that but like I said I isolated it so nothing else touches them it just does that. – Justin Meiners Sep 06 '10 at 04:57
  • @Chuck yeah I know but if the point that it is crashing in is where no autoreleased objects exist and its crashing inside apples code I start to wonder if they wrote good memory managment for it. – Justin Meiners Sep 06 '10 at 14:24

4 Answers4

2

This was a hard one to solve partly because debugging memory behaves inconsistently.

I have 2 classes JGStaticModel and JGModel. For some reason, the unarchiver would pick one of those at random so sometimes initWithCoder was sent to JGModel and not JGStaticModel. This led me to think it was not being called. Also since their structure is slightly different it had issues and crashed. The reason why I got the autorelease problem was I patched some memory problems in JGStaticModel but not JGModel so it would crash on the memory because I had not fixed it there.

Thanks for all the help!

Justin Meiners
  • 10,754
  • 6
  • 50
  • 92
1

Try turning on NSZombieEnabled, this should help you track down the problem.

AndersK
  • 35,813
  • 6
  • 60
  • 86
0

If neither tools (Run -> Run with Performance tools) and NSZombiesEnabled helps, you can override - (id)retain and - (void)release methods of the class that caused the exception. Call super implementation and log retain/release. You can break in this methods to see the call stack. This way isn't beautiful, however, it helped me few time to figure out where was an extra release/autorelease call

Gobra
  • 4,263
  • 2
  • 15
  • 20
0

This problem is very easy to solve with the solution given here.

The relevant part is:

If an environment variable named "NSAutoreleaseHaltOnFreedObject" is set with string value "YES", the function will automatically break in the debugger

Community
  • 1
  • 1
Coyote
  • 2,454
  • 26
  • 47