Help! A zombie is after my application!

Ok, I run into the good old “dangling pointer” gag, at last!

My app crashes repeatedly when my last window is closed. The crash messages are not always the same – many things can happen when the last window is closed. For example, I got something like "application should close when the last window is closed >bang<

The last line was always “libobjc.A.dylib 0x00007fff8cc9a150 objc_msgSend_vtable5 + 16”

Believe it or not, there are numerous web reference for this message, and every time the solutions are different, too. Fortunately we don’t see the “reformat the hard drive and make a clean installation of the system” sentence anymore.

Anyway, I used Instruments and tested allocations, leaks. and finally zombies. And when the last window of my app was closed, I saw “Zombie Messaged
An Objective-C message was sent to a deallocated object (zombie) at address: 0x104155400.

ARC, I thought your were my friend. Sob.

Well, the little rascal appears to be a table column. Now. Why is this column called, and what is sending a message to this deallocated object? And why only for the last window (there is no problem as long there is one window opened)?

I have numerous columns in my app, in two windows and two drawers. I originally thought there was a problem with AutoSave, so I gave a name to every column. But normally Xcode warns “your column must be compliant” or something like that. I knew it was not the problem. And it was not, the zombie hides elsewhere.

The zombie is called precisely when the pointer reaches the “File” menu. Not before. Not another menu. No need to click. >BANG<

Does it remind something to someone of you? Some precisions: this is the Core Data version of my app: the non-Core version does not have the problem. Not to mention the ASOC version.

Any clue very, very welcome!

Regards,

If it is any help the objc_msgSend_vtable5 is a shortened/optimized version respondsToSelector:

My source

Hi DJ,

Of course it helps !

As I suspected, the only known call to respondsToSelector is issued by a third-party NSActionCell subclass, which was written for a non-GC application. As ARC does not allow explicit deallocation, I’m a bit annoyed now.

Second problem: why does only the last window which causes problem?

I suppose (as the cell attempts to communicate with a dead delegate) that I have do put this instance variable to nil [theCell setDelegate: nil] somewhere, but where is the best place to do so?

And by the way, is it a table somewhere giving the error codes – as there will certainly be others?

Regards,

Simplest way to check if it’s an arc issue is just turning it off. Your application will have dozens maybe thousands of memory leaks but your application should continue running. As soon as the application gets terminated (better said: when the process gets terminated) the kernel will free all of it’s memory that is in use.

You can catch immediately your second problem as well. If you app continues without arc it means you deallocate too much.

No it’s an message, so when an object gets removed from the hash table by deallocating, every delegate automatically point to NULL who was pointing to the object before.

Address Category Event Type RefCt Timestamp Size Responsible Library Responsible Caller

43 0x103c2b630 NSTableColumn Release 2 00:01.635.431 0 Foundation -[NSClassicMapTable dealloc]
44 0x103c2b630 NSTableColumn Release 1 00:01.635.848 0 Foundation -[NSClassicMapTable dealloc]
45 0x103c2b630 NSTableColumn Release 0 00:13.327.918 0 AppKit -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:]
46 0x103c2b630 NSTableColumn Zombie -1 00:19.441.317 0 AppKit -[NSApplication supplementalTargetForAction:sender:]

What could make this column become a zombie? If an object keeps a reference to this column, the counter shouldn’t become 0.

Anyway. once again the message is different:

0 com.apple.CoreFoundation 0x00007fff8d02ad57 forwarding + 167
1 com.apple.CoreFoundation 0x00007fff8d02ac38 _CF_forwarding_prep_0 + 232
2 com.apple.AppKit 0x00007fff8fbca814 -[NSApplication supplementalTargetForAction:sender:] + 63
3 com.apple.AppKit 0x00007fff8fab91e4 _objectFromResponderChainWhichRespondsToAction + 155

DJ, with or without ARC, the app crashes.

I found something which seems to solve the problem. But I don’t understand what’s happening and I really dislike this.

In IB, the file’s owner has a “window” outlet who points to the document window; but there is no @property NSWindow window; in the default code of the NS(Persistent)Document.

I had to make a panel a “child window” of the doc’s main window, so I add a @property NSWindow mainWindow. The new “mainWindow” outlet points to the same window as the “window” outlet.

And suddenly no more crash, no more zombie. What happened? I’m baffled.

You added an extra pointer to the window so ARC will never get to 0 and that’s why the window never got released.

OK, it’s clear now. I suppose that objects are arbitrarily released and this NSTableColumn was the first to be targeted, but. too late.

Er. I wonder if Core Data + ARC are working well together. This obscure reference to “window” property into the fileOwner (a “proxy” :confused: for an instance of the NSApplication class) which was not reflected in the code of NSDocument did not retain my attention – before the zombies crawled out of their tombs.

I think that a deallocated window sends a message to each subview: “Hey, guys, I’m going to die, please commit suicide” or something like this. This message should propagate to every concerned object, and if one of them in the chain says “Wait a minute, there is still a pointer to me, stooooop” then this cancel message goes backwards and the window/document/application raises an exception. no?

Anyway. I was confident as Apple said this should never happen. And actually it is my first zombie in more than one year: Am I particularly lucky or not?