Re: Zombie object being messaged - why?
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?
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?
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?
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?
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?
(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?
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?
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?
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