I have a working program that was written by another programer that I am trying to add some features to in an effort to learn the iPhone SDK. I have carried out what I would assume was a fairly simple task of adding an additional UIButton to an existing view with like buttons. I have used the other UIButtons as a model and it seems this should be a simple task.
The problem is when the line that calls this subview is executed I get the rather vague error flag of TERMINATING_DUE_TO_UNCAUGHT_EXCEPTION. Where do I find more information on this error code? I looks to me like a very general error and certianly there must be someplace in the Xcode shell that gives me more detail on what this means?
I have isolated the line where it occurs and it seems to happen on the first reference to the new view. Is it a problem with the connections made in interface builder? Any suggestions would be helpful as I really feel like I am grasping at straws at this point...
You want want to trap the exception when it happens, you might then be able to track it down in the debugger. A useful set of breakpoints to use when your debugging Cocoa apps are objc_exception_throw and -[NSException raise]. In the iPhone I think all exceptions travel through objc_exception_throw but if your were targetting Tiger or earlier you should set a breakpoint on both.
There are more debugging techniques at http://www.cocoadev.com/index.pl?DebuggingTechniques.
This is an exception generated by the Objective-C runtime. Hit CMD-SHIFT-R to bring up the debugger console. You'll see all the gdb startup information at the bottom of the window, but if you scroll up past the stack info, you'll get to something that should look like this:
[Session started at 2009-04-09 14:39:27 -0700.]
2009-04-09 14:39:31.246 LearnGLES[10415:20b] *** -[EAGLContext fakeMessage]: unrecognized selector sent to instance 0x528150
2009-04-09 14:39:31.248 LearnGLES[10415:20b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[EAGLContext fakeMessage]: unrecognized selector sent to instance 0x528150'
2009-04-09 14:39:31.250 LearnGLES[10415:20b] Stack: (
2517758219,
2486509115,
....
That's just a complete sample exception that I made up by changing code to send a non-existent message to an object, but there are a lot of possibilities as to what yours might be. Anything that would generate a run-time exception in any of the Objective-C frameworks could be the culprit (un-parseable dates to a date formatter, invalid messages to objects, etc...)
It probably means that you used some memory after deallocating it or used it without initializing it. Often when you look at the stack after this all you'll see is the part of the main loop that performs the autoreleases, which clearly isn't going to help you.
Really you need to get a good understanding of how memory management works in Objective-C and then take a look at your changes. There's not really a silver bullet here. The good news is that it gets easier with experience.
This is a nice article about debugging in Objective-C.
What connections have you made in interface builder? Are you making a call to any methods when the button is clicked? What is the method signature in that case? Have you made any changes to the original code, where you might have accidentally deleted some code which was important. It would help if you post some code. The exception is very generic.
I had a similar problem when I released things that I had not explicitly allocated.
In my case, I had a background image UIImage *image=[UIImage ...] and was setting it to be the background of my UIButton, and then did [image release];
You don't want to do the [image release]: the UIButton owns it now, and it will free it when no longer needed.
Maybe you have a similar issue?
Related
I am trying to access the UITextView delegates and have a problem
I have a UIViewController with the UITextViewDelegate protocol and a Nib containing the textView.
If I set the delegate inside viewDidLoad like "textView.delegate = self" and I touch the textView, the app crashes without logging errors.
If I start editing the textView with code like "[textView becomeFirstResponder]" all delegates get called.
When I set the delegate in the Nib creating a connection between the textView and the File's owner and deleting "textView.delegate = self" also no delegates get called.
What am I doing wrong here?
Regards,
Elias
It's not easy to help you without more description, posted code or a xib file.
You say application crashes without any logging errors - well, do you mean that there's no output in console's window ? That is normal, for an app that has crashed.
Anyway, you should be able to get the stack-trace to figure out where approximately the application has crashed. Open the debugger (⇧⌘Y), and see the position. That should give you an idea of what went wrong.
Here you can see an example of such debugger session (after EXC_BAD_CRASH):
First two lines doesn't give us much information, but later on we can see that application has crashed while loading user interface from a NIB file. Well, usually the only code that executes during such load are awakeFromNib methods - it's up to you to find a problem along those lines.
Often top of code's execution doesn't make any sense - for example you might see your ViewController method somewhere, but the top few function calls (those where the code crashed) are located in methods/classes which you never call in your code. In most cases that is a sign of wrong memory de-/allocation. What might happened is that you forgot to retain some of your objects, it has already been released, but you are still keeping reference (a pointer) to its memory. Because that memory has been in fact freed, another object took its place later on, usually some Apple's internal object you've never heard about. Later on your code tries to message your poor object but it sends a message to something completely different. BUMMER! That's how you get those crashes and strange stack traces.
To fix the kind of problem I've just described you can use Instruments and its Zombies instrument. Unfortunately you can't start Zombies from within Xcode, you need to start Instruments standalone, then choose the Zombies under iPhone Simulator/Memory, then Choose Target from the toolbar, you should see your application in there, or be able to navigate to it on filesystem.
What Zombies instrument does is that it never really frees memory after objects are deallocated. Instead, it will mutate those objects into NSZombie class. That class intercepts all calls to itself, and informs you when some code is trying to send a message to it.
This is how such Instruments session looks like (this is the same crash as seen in debugger above):
In the table you can see that we're trying to message UIScrollView that has already been deallocated. You can as well see the whole history of retain/release calls to this particular object. That way you can find a missing retain or wrong release/autorelease.
Remember - Zombies Instruments can only be used with Simulator, because there's not enough memory on the real device to keep all those memory blocks.
Hopefully I could help you with further analysis of your problem.
I have a memory leak, so i tried to debug with nszombie....
And NSZombie printed this:
-[MobileOfferViewController _shouldUseKeyWindowStack]: message sent to deallocated instance 0x6307580
So my question: what is the method: shouldUseKeyWindowStack??
Found nothing on Google....
Thanks,
Martin
I fought with a similar error for quite some time. Best I can tell, _shouldUseKeyWindowStack is an internal UIResponder method that showed up in iOS 4.0 (I assume related to multitasking somehow).
However, the real error with this type of thing is usually a memory access error (too many releases on an object, or a threading error). In my case, it was a threading error - specifically, trying to update the UI (show a UIAlert) in a background thread. I ended up wrapping the code that was causing the crash in it's own method and then calling [self performSelectorOnMainThread:withObject:waitUntilDone:] to work around the crash.
I've spent two days on this and I still can't find the cause of the crash.
I know it has something to do with trying to access an object that has been freed but I don't know which access or which object.
Whenever I google trying to find the source of EXC_BAD_ACCESS people suggest using NSZombies. The problem is when I enable zombies (either in xcode via environment variable or in instruments via ObjectAlloc properties) the program doesn't crash where it usually does and the zombies don't report anything (nothing shows up in logs and nothing is flagged in instruments). Is there something I'm missing with NSZombie?
I've tried utilizing some information from xcode's debugger and from ObjectAlloc in instruments but all the information is very cryptic and doesn't really help me.
I've set the debugger to stop on objective-c exceptions. When it does it this is the call stack shown:
0 objc_msgSend
1 ??
2 -[UITableViewCell removeFromSuperView]
3 -[UIView dealloc]
... etc ...
First of all, what's the deal with '1 ??' ? What do the question marks mean? Second of all how can I know where this was called in my code? All the operations stated are too generic (eg UIView dealloc, but which UIView? And where?).
Also when the exception occurs it points to assembly code which again, doesn't do me any good unless I was to spend hours trying to figure out what the code does. I know some assembly but there has to be a better way... right?
Is there any way I can get meaningful information as to what was the last line that ran in my code before the exception occurred?
I've tried sprinkling some NSLogs and breakpoints around but it doesn't help me much because the crash happens after I pop a view controller from a navigation controller. Everywhere I place breakpoints the breakpoints are reached fine (I can't find a point to break after the crash). It's only when I 'continue' in the debugger that the exception occurs. It's as if the crash happens outside of my code so I have no idea where to get a handle on it.
I've looked through my code and double checked that I adhere to all the memory management rules (at least to the best of my knowledge). I'm sure it's something very subtle but I can't seem to find it.
If anyone has any ideas how to find such bugs without NSZombie please share.
Thanks.
Well I found the problem. I had a custom table cell class in which I called [super dealloc] first in the dealloc method (rather than last). I guess I wrote this class in a hurry and didn't really think about it. I'm guessing something got released in the parent that the child needed for releasing?
So I don't have a real answer to my own question but basically I found the problem using a combination of ad-hoc code tracing and various debugging techniques (breakpoints, NSLogs, trying to decypher cryptic stack trace,etc).
Actually the main strategy that helped me was commenting out code bit by bit until I stripped down the problem area into as simple as it gets while still keeping the crash intact. This let me realize the problem wasn't where I thought it would be but in a more subtle area (eg in the dealloc method of a secondary class in this case).
I hope this can sort of help someone out. I'll leave this question unanswered for a bit incase someone has a more thorough debugging strategy without relying on NSZombies. Also if someone can clarify what those two question marks mean in the stack trace that would be helpful.
So I'm getting a EXC_BAD_ACCESS error in cocos2d. From what I've been searching so far it's mostly related to attempting to free an object which has already been released. I have encountered this error before, and its solution was simple and pretty much caused by freeing a released object. But now, using cocos2d (not sure if it's a bug in their framework or not), I'm getting an EXC_BAD_ACCESS in this line:
CCMenuItemSprite *btn = [CCMenuItemSprite itemFromNormalSprite:op selectedSprite:op target:self selector:NSSelectorFromString([sceneMethods objectAtIndex:i])];
Basically, I'm creating a simple menu system for easy maintenance and updating. Nothing too serious. In this particular line, I'm creating a CCMenuItemSprite with self as target and using a selector. I've already asserted that the selector passed as argument is correct and also tried to use different for the normal and selected sprite (though that shouldn't make any difference) but still no go! The error is deep in the cocos2d framework, precisely when the CCMenuItem is "activated" which calls invoke on a NSInvoker of that same class. And analyzing the stack trace, it crashes exactly on the invoke method, which leads to believe it has something to do with the NSInvoker. Anyone had a similar problem or have a suggestion for this problem? Thanks in advance.
Just a guess: are you completely sure that all of the objects in sceneMethods are real selectors?
I'm a little ways into developing my first iphone app, and I've been running into exc_bad_access a lot. (I'm sure it's because I'm not designing stuff in a very MVC-proper way yet.)
It's extremely frustrating trying to hunt down why I'm running into these errors all the time... is there a way in the xcode debugger to keep a watch list of pointers, so you can actually see when various objects are being released? Something, anything that can give me more of a visual understanding of why my program design is flawed?
In particular, I keep having trouble with my "webobject" class I've wrapped all of my NSURLConnection methods in. When I try to call performselector to the view controller that initiated a "webobject" request, I keep getting exc_bad_access when I try to access the webobject's synthesized properties. Is there something fundamentally wrong with my notion that I should wrap all of my webservice-related methods into a class that I can import anywhere?
Dave,
I don't know of a way to trace the deallocation of objects (especially native objects like NSStrings). But, I experienced a similar abundance of exc_bad_access messages when starting Objective-C programming. But one day I read something that helped me alot to get rid of these messages:
If you create an object using alloc, copy, or a method that begins with new, then it is your object to manage and dealloc. You can call retain and release and that cycle will work as expected on those objects. If you never call release or dealloc on it, it will hang around foreever and be a leak. If you call a method that is something like 'stringWithFormat', numberWithYadaYada then that object is set for autorelease. Meaning, as soon as you exit the method that is using it, it may get dealloced. Therefore, if you've called one of these autorelease methods, you must retain it if you want to see it later on.
I suspect that either your delegate or NSURLConnection is getting autoreleased, that is the cause of your bad access messages.
Jack
You could try creating a breakpoint on -[NSObject dealloc] (or the same method on the subclass you are targetting).
I would also refer you to one of the many Cocoa memory handling tutorials.
I ended up reading up about NSZombieEnabled, which has helped me track down those exc_bad_access messages. More info here: http://www.cocoadev.com/index.pl?NSZombieEnabled
Just as a general thing, you should run as a static analyzer and it will probably tell you when you are over or under retaining objects.
pertinent stackoverflow question