Re: Zombie object being messaged - why?

2013-01-25 Thread Keary Suska
On Jan 25, 2013, at 8:52 AM, Martin Hewitson wrote:

 In a document based app running under ARC, I've been struggling for an 
 eternity to get to the bottom of an occasional crash which happens when 
 closing a document. I've spent a huge amount of time working on my -tearDown 
 procedure which I call in my NSDocument subclass' -windowWillClose: and which 
 subsequently calls -tearDown on many other app components. I also hit the 
 same crash:
 
 [MHControlsTabBarController performSelector:withObject:]: message sent to 
 deallocated instance 0x1075d2cb0

First things first--you are getting a crash, which means that the debugger 
should put you exactly in the place where you can inspect the arguments being 
sent via this method which will likely tell you what object is sending it and 
potentially why. Without this knowledge, everything you do is just random stabs 
and may not solve the problem even if it seems to go away.

Just a quick suggestion--have you searched your code to see if you ever call 
this method?

 MHControlsTabBarController is a view controller whose view is added to the 
 document's main window when the document loads.
 
 In my document's -tearDown I do:
 
  // clean up tab bar controls
  [self.controlsTabBarController tearDown];
  self.controlsTabBarController = nil;
 
 In [MHControlsTabBarController tearDown] I nil out various state variables. 
 I've also tried various things in that -tearDown, like removing the view 
 controller's view from the superview, cancelling any run loop performs by 
 doing:
 
  [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget:self];
  [[NSRunLoop mainRunLoop] cancelPerformSelectorsWithTarget:self];

IIRC performSelector:withObject: is not a run loop action--it is immediate 
dispatch, so doing the above is one of those useless stabs I mentioned.

 nilling out all IBOutlets, etc, but nothing helps so far.

 Should I interpret this as a window trying to message the object?  Am I 
 somehow over-reasling? Under ARC, I can't, right? If it's not coming from a 
 window, how can I figure out which object is trying to message this 
 deallocated MHControlsTabBarController? 

If you are using ARC, I don't think you should be doing any explicit memory 
management except to explicitly balance other explicit memory management calls; 
and if you aren't, then you aren't over-releasing. Minimally, some object has a 
weak reference to your MHControlsTabBarController, and that can happen, so once 
you know who and why you can prevent it.

 There are a number of timer-based activities which check the state of this 
 controls controller but in the document's -tearDown I try to stop all timers. 
 The problem is, how can I ensure that all timers (and any actions already 
 triggered) have stopped, before I go ahead tearing down everything else? I 
 sort of need to delay the document closing somehow, but I asked about this in 
 an earlier thread (this has been a lng story) and was advised (probably 
 rightly) that this was bad design. But this seems like a general problem to 
 me, for which there is surely a general pattern which solves it. If I have 
 timer-based activities, how do I make sure they are stopped before the rug is 
 pulled from under their feet?

Whichever object set up the timers should invalidate them before their target 
would be released, so the validity of the target should be known and 
deterministic to that object. Sometimes easier said than done, but there it is. 
In any case it is not likely that a timer is responsible since they are 
supposed to retain or maintain a strong reference to their target until they 
are invalidated, after which time they would not fire anyway.

HTH,

Keary Suska
Esoteritech, Inc.
Demystifying technology for your home or business


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Zombie object being messaged - why?

2013-01-25 Thread Andy Lee
On Jan 25, 2013, at 10:52 AM, Martin Hewitson martin.hewit...@aei.mpg.de 
wrote:
 Should I interpret this as a window trying to message the object?  Am I 
 somehow over-reasling? Under ARC, I can't, right?

Assuming there isn't a bug in ARC, you could still be over-releasing if:

* You're supporting 10.6 and so you're using __unsafe_unretained because you 
can't use __weak.
* You've incorrectly used the __bridge keywords somewhere, like maybe you used 
__bridge or __bridge_transfer when you should have used __bridge_retained.

--Andy


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Zombie object being messaged - why?

2013-01-25 Thread Greg Parker
On Jan 25, 2013, at 7:52 AM, Martin Hewitson martin.hewit...@aei.mpg.de wrote:
 2117  0x10a395410 MHControlsTabBarController  Zombie  -1  
 03:31.405.789   0   AppKit  -[NSWindow sendEvent:]
 
 Should I interpret this as a window trying to message the object?  Am I 
 somehow over-reasling? Under ARC, I can't, right? If it's not coming from a 
 window, how can I figure out which object is trying to message this 
 deallocated MHControlsTabBarController? 

First, you should get the full stack trace for the zombie message. That might 
help identify who's doing what. 

One common failure that ARC does not fix is traditional delegates in AppKit and 
other system frameworks. For various reasons those delegates are 
__unsafe_unretained instead of ARC __weak. That means if you forget to clean up 
some delegate somewhere then AppKit's will be left with a dangling pointer. 
Then AppKit tries to use the delegate later and crashes.

Controller objects are often used as delegates so I bet something like this is 
going on. If so, the stack trace of the zombie message will probably show 
AppKit calling -respondsToSelector: or one of the delegate methods on your 
zombified controller object.


-- 
Greg Parker gpar...@apple.com Runtime Wrangler



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Zombie object being messaged - why?

2013-01-25 Thread Quincey Morris
On Jan 25, 2013, at 10:33 , Quincey Morris 
quinceymor...@rivergatesoftware.com wrote:

 Since the retain count goes from 1 to 0 here

Aargh, did it again! The count is actually going from 2 to 1 in your history.

I meant of course, discounting the balanced retain/release pairs, it's the last 
remaining retain count being decremented. 

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Zombie object being messaged - why?

2013-01-25 Thread Martin Hewitson
Hi Keary, 

I appreciate your response. I'll try to answer below.


 
 In a document based app running under ARC, I've been struggling for an 
 eternity to get to the bottom of an occasional crash which happens when 
 closing a document. I've spent a huge amount of time working on my -tearDown 
 procedure which I call in my NSDocument subclass' -windowWillClose: and 
 which subsequently calls -tearDown on many other app components. I also hit 
 the same crash:
 
 [MHControlsTabBarController performSelector:withObject:]: message sent to 
 deallocated instance 0x1075d2cb0
 
 First things first--you are getting a crash, which means that the debugger 
 should put you exactly in the place where you can inspect the arguments being 
 sent via this method which will likely tell you what object is sending it and 
 potentially why.

Unfortunately, either that isn't happening, or I'm not understanding what I 
see. Here's an example backtrace:

[MHControlsTabBarController performSelector:withObject:]: message sent to 
deallocated instance 0x104bc33f0
(lldb) bt
* thread #1: tid = 0x1d07, 0x7fff8ff5f4ce CoreFoundation`___forwarding___ + 
158, stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
frame #0: 0x7fff8ff5f4ce CoreFoundation`___forwarding___ + 158
frame #1: 0x7fff8ff5f3b8 CoreFoundation`_CF_forwarding_prep_0 + 232
frame #2: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #3: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #4: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #5: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #6: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #7: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #8: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #9: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #10: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #11: 0x7fff93648a83 AppKit`-[NSWindow sendEvent:] + 7994
frame #12: 0x7fff9364442c AppKit`-[NSApplication sendEvent:] + 4969
frame #13: 0x7fff9355a2fa AppKit`-[NSApplication run] + 636
frame #14: 0x7fff934fecb6 AppKit`NSApplicationMain + 869
frame #15: 0x00011d02 TeXnicle`main + 34 at main.m:32
frame #16: 0x00011cd4 TeXnicle`start + 52


Here's another example:

[MHControlsTabBarController performSelector:withObject:]: message sent to 
deallocated instance 0x127ef9fd0
(lldb) bt
* thread #1: tid = 0x1d07, 0x7fff8ff5f4ce CoreFoundation`___forwarding___ + 
158, stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
frame #0: 0x7fff8ff5f4ce CoreFoundation`___forwarding___ + 158
frame #1: 0x7fff8ff5f3b8 CoreFoundation`_CF_forwarding_prep_0 + 232
frame #2: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #3: 0x7fff93648a83 AppKit`-[NSWindow sendEvent:] + 7994
frame #4: 0x7fff9364442c AppKit`-[NSApplication sendEvent:] + 4969
frame #5: 0x7fff9355a2fa AppKit`-[NSApplication run] + 636
frame #6: 0x7fff934fecb6 AppKit`NSApplicationMain + 869
frame #7: 0x00012022 TeXnicle`main + 34 at main.m:32
frame #8: 0x00011ff4 TeXnicle`start + 52

 Without this knowledge, everything you do is just random stabs and may not 
 solve the problem even if it seems to go away.

That's exactly how I feel. I just keep trying things, but nothing seems very 
systematic. Most unsatisfying.

 
 Just a quick suggestion--have you searched your code to see if you ever call 
 this method?

No, I never message MHControlsTabBarController with performSelector:...

 
 MHControlsTabBarController is a view controller whose view is added to the 
 document's main window when the document loads.
 
 In my document's -tearDown I do:
 
 // clean up tab bar controls
 [self.controlsTabBarController tearDown];
 self.controlsTabBarController = nil;
 
 In [MHControlsTabBarController tearDown] I nil out various state variables. 
 I've also tried various things in that -tearDown, like removing the view 
 controller's view from the superview, cancelling any run loop performs by 
 doing:
 
 [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget:self];
 [[NSRunLoop mainRunLoop] cancelPerformSelectorsWithTarget:self];
 
 IIRC performSelector:withObject: is not a run loop action--it is immediate 
 dispatch, so doing the above is one of those useless stabs I mentioned.

Ah, good to know. So I don't need to do that.

 
 nilling out all IBOutlets, etc, but nothing helps so far.
 
 Should I interpret this as a window trying to message the object?  Am I 
 somehow over-reasling? Under ARC, I can't, right? If it's not coming from a 
 window, how can I figure out which object is trying to message this 
 deallocated MHControlsTabBarController? 
 
 If you are using ARC, I don't think you should be doing any explicit memory 
 management except to explicitly balance other explicit memory management 
 calls; and if you aren't, then you aren't over-releasing. 

Re: Zombie object being messaged - why?

2013-01-25 Thread Quincey Morris
(resent)

On Jan 25, 2013, at 07:52 , Martin Hewitson martin.hewit...@aei.mpg.de wrote:

 2111  0x10a395410 MHControlsTabBarController  Retain  2   
 03:29.823.791   0   TeXnicle-[TeXProjectDocument 
 controlsTabBarController]
 2112  0x10a395410 MHControlsTabBarController  Autorelease 
 03:29.823.792   0   TeXnicle-[TeXProjectDocument 
 controlsTabBarController]
 2113  0x10a395410 MHControlsTabBarController  Retain  3   
 03:29.823.792   0   TeXnicle-[TeXProjectDocument tearDown]
 2114  0x10a395410 MHControlsTabBarController  Release 2   
 03:29.825.781   0   TeXnicle-[TeXProjectDocument tearDown]
 2115  0x10a395410 MHControlsTabBarController  Release 1   
 03:29.825.784   0   TeXnicle-[TeXProjectDocument 
 setControlsTabBarController:]
 2116  0x10a395410 MHControlsTabBarController  Release 0   
 03:29.877.132   0   Foundation  -[NSAutoreleasePool drain]
 2117  0x10a395410 MHControlsTabBarController  Zombie  -1  
 03:31.405.789   0   AppKit  -[NSWindow sendEvent:]
 
 Should I interpret this as a window trying to message the object?  Am I 
 somehow over-reasling? Under ARC, I can't, right? If it's not coming from a 
 window, how can I figure out which object is trying to message this 
 deallocated MHControlsTabBarController? 

I think there's a bit more information here than you think.

Yes, the view controller is being messaged because your window is processing an 
event. I'll come back to this in a minute.

First, we can winnow the history in two stages:

-- Ignore the retain and release from 'tearDown', since those are balanced.

-- Ignore the retain/autorelease from 'controlsTabBarController' and the 
balancing release in 'drain'.

That leaves this:

 2115  0x10a395410 MHControlsTabBarController  Release 1   
 03:29.825.784   0   TeXnicle-[TeXProjectDocument 
 setControlsTabBarController:]

and there's every indication this is the 'self.controlsTabBarController = nil' 
you showed earlier in your message. Since the retain count goes from 1 to 0 
here, there shouldn't be any remaining references to the view controller. But 
there is one, as your crash proves. There are two possibilities:

1. You have a simple memory management bug where you overreleased the view 
controller, likely when you initially put its value in the 
'_controlsTabBarController' ivar (or whatever it's called) that backs the 
controlsTabBarController property.

2. The remaining reference is unretained.

If it's #1, it shouldn't be too hard to find. At worst, you might have to go 
through the whole Instruments history matching things.

If it's #2, it can be harder to find, but the 'sendEvent:' message is an 
excellent clue. Why would a window, dispatching an incoming event, send a 
message to a view controller? Well, normally it won't. It's going to transform 
the event into a NSResponder message and send it to something in the responder 
chain, and normally view controllers *aren't* in the responder chain.

But it does send it to the view controller! My conclusion is that you put the 
view controller in the responder chain yourself, and you forgot to take it out. 
This accords with #2, because it's unlikely you *retained* the view controller 
before adding it to the responder chain.

Note that I say you, but it might of course have been done by a 3rd party 
library or some code you don't have direct knowledge of.

Anyway I would suggest you investigate both #1 (by further examining your code 
for memory management errors, and winnowing the full Instruments history of the 
object) and #2 (to understand which presumably-unretained reference is being 
used for the zombie messaging).




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Zombie object being messaged - why?

2013-01-25 Thread Keary Suska
On Jan 25, 2013, at 11:51 AM, Martin Hewitson wrote:

 First things first--you are getting a crash, which means that the debugger 
 should put you exactly in the place where you can inspect the arguments 
 being sent via this method which will likely tell you what object is sending 
 it and potentially why.
 
 Unfortunately, either that isn't happening, or I'm not understanding what I 
 see. Here's an example backtrace:

You may not be able to access the arguments when you have zombies enabled. Turn 
it off, and when the debugger breaks, po the arguments. The selector is most 
useful to know, but also knowing the object argument will clue to why your 
instance is getting the message.

The backtrace seems to show that your instance is still in the responder chain, 
and knowing the above arguments will tell you whether its delegation or 
something else.

 [MHControlsTabBarController performSelector:withObject:]: message sent to 
 deallocated instance 0x104bc33f0
 (lldb) bt
 * thread #1: tid = 0x1d07, 0x7fff8ff5f4ce CoreFoundation`___forwarding___ 
 + 158, stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
frame #0: 0x7fff8ff5f4ce CoreFoundation`___forwarding___ + 158
frame #1: 0x7fff8ff5f3b8 CoreFoundation`_CF_forwarding_prep_0 + 232
frame #2: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #3: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #4: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #5: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #6: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #7: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #8: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #9: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #10: 0x7fff93680ef7 AppKit`forwardMethod + 125
frame #11: 0x7fff93648a83 AppKit`-[NSWindow sendEvent:] + 7994
frame #12: 0x7fff9364442c AppKit`-[NSApplication sendEvent:] + 4969
frame #13: 0x7fff9355a2fa AppKit`-[NSApplication run] + 636
frame #14: 0x7fff934fecb6 AppKit`NSApplicationMain + 869
frame #15: 0x00011d02 TeXnicle`main + 34 at main.m:32
frame #16: 0x00011cd4 TeXnicle`start + 52


Keary Suska
Esoteritech, Inc.
Demystifying technology for your home or business


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Zombie object being messaged - why?

2013-01-25 Thread Martin Hewitson
This was held for moderation for being too large (for some reason), so I've 
trimmed it and resent it.

 
 Should I interpret this as a window trying to message the object?  Am I 
 somehow over-reasling? Under ARC, I can't, right? If it's not coming from a 
 window, how can I figure out which object is trying to message this 
 deallocated MHControlsTabBarController? 
 
 I think there's a bit more information here than you think.
 
 Yes, the view controller is being messaged because your window is processing 
 an event. I'll come back to this in a minute.
 
 First, we can winnow the history in two stages:
 
 -- Ignore the retain and release from 'tearDown', since those are balanced.
 
 -- Ignore the retain/autorelease from 'controlsTabBarController' and the 
 balancing release in 'drain'.
 
 That leaves this:
 
 2115 0x10a395410 MHControlsTabBarController  Release 1   
 03:29.825.784   0   TeXnicle-[TeXProjectDocument 
 setControlsTabBarController:]
 
 and there's every indication this is the 'self.controlsTabBarController = 
 nil' you showed earlier in your message. Since the retain count goes from 1 
 to 0 here, there shouldn't be any remaining references to the view 
 controller. But there is one, as your crash proves. There are two 
 possibilities:
 
 1. You have a simple memory management bug where you overreleased the view 
 controller, likely when you initially put its value in the 
 '_controlsTabBarController' ivar (or whatever it's called) that backs the 
 controlsTabBarController property.

I always use self.controlsTabBarController - I don't directly access the 
backing ivar anywhere.

 
 2. The remaining reference is unretained.
 
 If it's #1, it shouldn't be too hard to find. At worst, you might have to go 
 through the whole Instruments history matching things.
 
 If it's #2, it can be harder to find, but the 'sendEvent:' message is an 
 excellent clue. Why would a window, dispatching an incoming event, send a 
 message to a view controller? Well, normally it won't. It's going to 
 transform the event into a NSResponder message and send it to something in 
 the responder chain, and normally view controllers *aren't* in the responder 
 chain.
 
 But it does send it to the view controller! My conclusion is that you put the 
 view controller in the responder chain yourself, and you forgot to take it 
 out. This accords with #2, because it's unlikely you *retained* the view 
 controller before adding it to the responder chain.

Ahh, this may be going in the right direction. I do:

self.controlsTabBarController = [[MHControlsTabBarController alloc] init];
[self.controlsTabBarController setNextResponder:self.mainWindow.nextResponder];
[self.mainWindow setNextResponder:self.controlsTabBarController];  

So I should explicitly remove self.controlsTabBarController from the responder 
chain in my -tearDown method?

OK, in my -tearDown I've inserted

  [self.mainWindow 
setNextResponder:self.controlsTabBarController.nextResponder];

before doing 

  [self.controlsTabBarController tearDown];
  self.controlsTabBarController = nil;

After a short amount of testing, I haven't had a crash. So the frequency, at 
least, has reduced. Maybe this even fixes the problem. Under the Zombies 
Instrument, I no longer get a zombie when closing documents. 


 
 Note that I say you, but it might of course have been done by a 3rd party 
 library or some code you don't have direct knowledge of.

No, probably 'you' was correct here.

 
 Anyway I would suggest you investigate both #1 (by further examining your 
 code for memory management errors, and winnowing the full Instruments history 
 of the object) and #2 (to understand which presumably-unretained reference is 
 being used for the zombie messaging).
 
 

Looking forward to your further thoughts on this,

Martin






___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Zombie object being messaged - why?

2013-01-25 Thread Quincey Morris
On Jan 25, 2013, at 22:39 , Martin Hewitson martin.hewit...@aei.mpg.de wrote:

 This was held for moderation for being too large (for some reason), so I've 
 trimmed it and resent it.

Yes, this happens sometimes when you paste something with formatting into an 
email as unformatted text. I don't think my post (that you're replying to here) 
ever got to the list, even though I tried to fix it and resend. Anyway, you've 
repeated the essentials.

 OK, in my -tearDown I've inserted
 
  [self.mainWindow 
 setNextResponder:self.controlsTabBarController.nextResponder];

This isn't perhaps entirely safe. If anything has inserted another responder 
between the window and your view controller, you're going to mess up the 
responder chain.

You should really walk the chain starting at the window, looking for the last 
thing before your view controller, and adjust *that* (which will generally be 
the window itself).

 Anyway I would suggest you investigate both #1 (by further examining your 
 code for memory management errors, and winnowing the full Instruments 
 history of the object) and #2 (to understand which presumably-unretained 
 reference is being used for the zombie messaging).
 
 Looking forward to your further thoughts on this,

I think your problem is solved. :)

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com