I have a pernicious EXC_BAD_ACCESS bug. I have enabled zombie tracking, but instead of producing a specific stack trace, the program always stops in main at
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
Does anyone know why I don't have a meaningful stack trace? The app uses core data and much of the core data activity is wrappedup in performBlockAndWait methods - could that have something to do with it?
I also have a log message from NSZombieEnabled that says *** -[_PFArray release]: message sent to deallocated instance 0x395d0fe0. Is there any way of finding out what was originally allocated at the address in the log message?
Thanks
yes there is. Run your app with he instruments ON THE SIMULATOR. Select the Zombies instrument and perform the exact steps that make your app crash. The Zombies instrument is available only on the Simulator since you have more RAM on the Mac than on an iOS device.
You can check this tutorial about crashes and figuring out what to do. Pay close attention to this part:
An exception happens when the program is caught doing something it
shouldn’t have done. What you’re looking at now is the aftermath of
this exception: the app did something wrong, the exception has been
thrown, and Xcode shows you the results. Ideally, you’d want to see
exactly where that exception gets thrown. Fortunately, you can tell
Xcode to pause the program at just that moment, using an Exception
Breakpoint. A breakpoint is a debugging tool that pauses your program
at a specific moment.
Related
Is there a way to prevent an EXC_BAD_ACCESS from crashing an app, like with #try..#catch you can handle an exception gracefully.
Update:
The code crashes when it attempts to dereference an invalid pointer. This is a third party library and it interfaces with external hardware so I can't debug locally. I am trying to prevent it from crashing and output data to a debugging console on my app.
In ObjC, try/catch do not handle exceptions particularly gracefully. You will still leak memory and leave the system in an undefined state. With rare exception, the expectation is that you are simply catching so you can log some things before crashing. And in general, you should not use #catch anywhere but at the top level of your program for this purpose. There are some extraordinary situations where limited use of exceptions may be appropriate, but they are rare in ObjC. See the Exception Programming Guide for some more information. See especially the following from the ObjC ARC documentation:
The standard Cocoa convention is that exceptions signal programmer error and are not intended to be recovered from. Making code exceptions-safe by default would impose severe runtime and code size penalties on code that typically does not actually care about exceptions safety. Therefore, ARC-generated code leaks by default on exceptions, which is just fine if the process is going to be immediately terminated anyway. Programs which do care about recovering from exceptions should enable the option [-fobjc-arc-exceptions, which imposes speed and memory penalties on your program].
The same is true of EXC_BAD_ACCESS. You can catch it with a signal handler for the purpose of recording some information and then finishing your crash. For a good tool for doing this see PLCrashReporter. It is very difficult to write such a handler correctly, so I strongly recommend using an existing framework. You can easily get into deadlocks that drain the user's battery if you catch EXC_BAD_ACCESS incorrectly.
You get EXC_BAD_ACCESS often because you sent a message to a released object. Then you can examine the NSZombie. What is an NSZombie? You can see : this. It will catch the
EXC_BAD_ACCESS because of sent a message to the released object.
You can set NSZombie like this : Check the Enable Zombie Objects
And you can also get EXC_BAD_ACCESS because of the memory warnings level is too high , or your memory is too high , so the apple will shut your app down. This EXC_BAD_ACCESS is too hard to prevent . I think the only way is to manage your memory as low as you can , sometimes you can see the log where is receive memory warning , when the level is high, it may getEXC_BAD_ACCESS
You can rewrite your code to not have these errors. Try not to reference any null pointers and keep references to any object that you want to have access to.
My iOS app is randomly crashing but I don't get any warning/error in the console. I think it might be a memory leak but shouldn't I receive a EXC_BAD_ACCESS error at least ?
The other thing might be a memory overloading, but I don't get any memory warning and I've just tested the app with the instruments tool.
So why does it crash without printing anything in the console ?
Thanks
UPDATE:
I'm actually getting a memory warning in the instruments although I don't see the memory to increase. COuld be the cause of the crash ? How do i know where is the memory warning generated ? (See screenshot: )
Tell your program to print a backtrace every time it receives a low memory warning.
From Apple documentation:
UIKit provides several ways to receive low-memory notifications, including the following:
Implement the applicationDidReceiveMemoryWarning: method of your
application delegate.
Override the didReceiveMemoryWarning method in
your custom UIViewController subclass.
Register to receive the
UIApplicationDidReceiveMemoryWarningNotification notification.
Enable Zombie objects and try again. https://stackoverflow.com/a/8050701/1271579
Edit: If the device runs out of memory, you will recieve a few memory warnings before crashing so you should probably optimize it.
I have a very strange problem and no idea what creates it nor how to solve it.
The app works fine under 10.5 and 10.6.
Under 10.7 the app start fine but crashes after about 15 secs later without any user interaction.
In the debugger console i see Program received signal: “EXC_BAD_ACCESS”.
I made a screenshot of the stacktrace and it seems as if it has something to do with NSPersistentUI.
So any hints and tips would be very appreciated.
I would try running with zombies enable, you haven't really given us enough information, I would guess you are not handling retain of objects between thread correctly, for example methods that are called by thread to get access to objects in another thread you should do a [myObject retains] autorelease] so to add the object to the calling threads autorelease pool.
Do you have Garbage Collector activated? Have you tried without it? I would suggest that. It is clearly MM problem and I would suggest you stick with retain/release.
I'm having a problem with a Cocoa application I am writing. It has to parse a timestamped file that is updated every hour, and during testing it keeps crashing consistently at around 11:45 PM due to a segmentation fault. I'm assuming I must be messaging an object that has been deallocated. What tools are provided with the Xcode install to track object allocations and (hopefully) tell me if I am messaging an object that has been deallocated?
I am using Mac OS X 10.5.
I would recommend the following:
Use NSZombieEnabled to monitor when messages are sent to deallocated NSObjects
Use Instruments to track object allocations and/or memory leaks
The way I do it is by using a command line tool called gdb. Here is a tutorial on how to use it. You'll have to learn a few of it's commands, but once you do it's almost a pleasure to use.
Note: gbd can be used on C, C++, and Objective-C programs.
Have you run the program under gdb? This should allow you to inspect the stack and variables when it SIGSEGVs.
To track allocations, use malloc_history. This requires the MallocStackLogging environment variable to be set.
A quick point: using a deallocated memory location usually results in a EXC_BAD_ACCESS exception. If that's the crash reason you're seeing then you're correct in assuming it's a deallocation problem.
Run it in Xcode's debugger (which is gdb with a GUI on top) and reproduce the crash. Then, look at the stack trace.
Messaging a deallocated object usually has the top frame in objc_msgSend. The next step then is to run the app with NSZombieEnabled and reproduce the crash; the zombie will identify itself.
I have a crash taking place when an NSAutoreleasePool drains. Presumably the pool is trying to deallocate an object that has been prematurely released by another piece of code. The crash I have is in the midst of objc_msgSend as it is trying to send a message to an object that doesn't exist anymore.
Given the stack state, what tips/tricks/processes/gdb commands do I have at my disposal to get information about the object in question and/or the point at which the illegitimate deallocation took place?
If you have a hunch that it is a premature deletion, enable zombies to confirm your hypothesis and then debug what is going on. When you enable zombies, objects are not really destroyed, but set to a zombie state, which helps you to detect when they are accessed after they dealloc is called. Read more from NSZombieEnabled
The definitive article on this kind of crash: http://www.sealiesoftware.com/blog/archive/2008/09/22/objc_explain_So_you_crashed_in_objc_msgSend.html
If you use NSZombieEnabled you can at least figure out what class the object is.
I came across what appeared to be a crash in objc_msgSend. What was even stranger was application:didFinishLaunchingWithOptions: was not even getting reached before the so called crash occured!
In my case the crash turned out to be a breakpoint that I had inadvertantly set on a memory address that was getting called before any of my code was even reached.
After the hour or so of trying to figure this out, I unchecked the breakpoint, ran the code, face palmed and then continued my day pretending it had never happened…