views:

271

answers:

1

I'm writing a simple ObjC2.0/Cocoa application, and I'm getting a crash.. Not being familiar with Cocoa or ObjC, I can't work out why..

The code causing the problems is TableListCon.m

When I drag a folder onto the NSTableView, it calls addDirectoryToList - which recursively loops over all files contained in this directory, calling addFileToList on each.

When I drag a single file onto the tableview, it calls addFileToList directly. This works correctly, but in the Debugger Console it shows following message:

tvnamergui(2612) malloc: *** error for object 0x144ab0: double free
*** set a breakpoint in malloc_error_break to debug

Or, if I drag-and-drop a folder there is no such messages, and it drops directly to GDB, with the following backtrace:

(gdb) bt
#0  0x95cee688 in objc_msgSend ()
#1  0x921e2e4f in NSPopAutoreleasePool ()
#2  0x917b4b10 in NSCoreDragReceiveProc ()
#3  0x95f9e1b0 in DoDropMessage ()
#4  0x95f9dc11 in CoreDragMessageHandler ()
#5  0x960f0d21 in __CFMessagePortPerform ()
#6  0x961128e8 in CFRunLoopRunSpecific ()
#7  0x96112cd8 in CFRunLoopRunInMode ()
#8  0x924892c0 in RunCurrentEventLoopInMode ()
#9  0x92489012 in ReceiveNextEventCommon ()
#10 0x92488f4d in BlockUntilNextEventMatchingListInMode ()
#11 0x914e0d7d in _DPSNextEvent ()
#12 0x914e0630 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#13 0x914d966b in -[NSApplication run] ()
#14 0x914a68a4 in NSApplicationMain ()
#15 0x000022a0 in main (argc=1, argv=0xbffff74c) at /Users/dbr/Desktop/tvnamergui/main.m:13

Even stranger, if I drag a single file first I get the double free error, but then I can drop folders on with no crashes (and all works perfectly)

It always dies when [ArrayCon addObject:cfile]; is run (commenting this line stops the crash, but obviously breaks the functionality!)

Edit: Thanks to smorgan's answer (Using NSZombieEnabled), I have a more useful error message:

*** -[CFArray release]: message sent to deallocated instance 0x155a70
+2  A: 

While I can't give a specific answer for your case, the best way to debug over-release crashes like this is to turn on NSZombieEnabled so you can easily see what object is being over-released.

Edit: After looking around your project, I believe your problem is actually in the AppCon initializer. You are setting your member variable "theFiles" to an autoreleased array, and while you are using a retaining (well, copying) property, you aren't setting it with property syntax (self.theFiles = ...), so you are bypassing the auto-generated setter that would handle memory management correctly. When something tries to update that property later, it will try to release the old value which was, incorrectly, not retained. That's most likely the array that you are seeing in the zombie logging.

In short, change

theFiles = [NSMutableArray arrayWithObjects:...];

to

self.theFiles = [NSMutableArray arrayWithObjects:...];

and make sure to always use self.foo (or the explicit [self setFoo:] form) when assigning to your properties.

smorgan
Aha, that produced a more useful error message (which I've added to the answer), thanks!
dbr
Perfect, thank you!
dbr