EXC_BAD_ACCESS and Address Sanitizer what's the next step? - swift

Have an app that's an iOS app with a Messages extension app. They share a significant amount of code related to calculating & editing the dimensions of some specialized objects and then using that to create paths for drawing.
The app was running perfectly. A build of the Messages app crashed with EXC_BAD_ACCESS code=2, seemingly within the code that's shared. No luck debugging it, as the location of the crash seemed to bounce around as I added log statements and refactored the code.
So I focused on the main app. First try was turning on Address Sanitizer, and that created the crashes discussed below. Then I edited the scheme to look for Zombies, and none were identified, including in Instruments. No memory leaks or other obvious allocation errors via Instruments. I edited the scheme to turn on Malloc Scribble, Malloc Guard Edges, and Guard Malloc, and the app ran fine with no crash or console log message.
So back to Address Sanitizer, which is the only option that caused the main app to crash, and it crashed in the same area as the Messages app. I figured if I solved one, I might solve both, and the app might be easier to debug without the complication of being an extension.
Every link I searched and read seemed to say that these Xcode diagnostics will (or should) identify the offending code, and in years of writing Swift, that's the typical case. This one has me stumped.
The main view controller is a UICollectionViewController, and the crash occurs at the very first collectionView(:cellForItemAt) call. There's nothing unusual about the other delegate calls, afaik, with normal (and accurate) counts and sizes. (And again, this is just with Address Sanitizer.) After getting the reusable cell, I call getObjectEffects with some default values (the app is more complex, but it crashed also on this ultra-simple hard-coded values case too, so I'm keeping the debugging as simple as possible), and the EXC_BAD_ACCESS is identified for the func definition of that function.
That's what stumps me. It's not identifying code where there's an assignment or allocation, but a func statement. And the parameters are Int and Bool. And there's zero output to the console, where I've also tried (lldb) command script import lldb.macosx.heap and (lldb) malloc_info —type 0x... with no result. As mentioned, I tried Zombies and the other Xcode memory management diagnostics with no insight into why Address Sanitizer is crashing at a func statement with an EXC_BAD_ACCESS, and I'm not sure how to diagnose this further.
What have I missed? Thanks for any insights.
Edit: Eventually made progress by switching code around and looking for different results. The eventual 'solution' is illogical in that I can't figure out how it should logically create any different result, but it does. And since it offers no insight into the original question of how to diagnose the cause of the EXC_BAD_ACCESS, I won't belabor it further here. For now, it'll be a 'solved' mystery.

Related

Mysterious inadequate stack traces in XCode give no context to where the error is occurring

I'm running into lots of instances with the latest version(s) of XCode (I believe this has been happening since 4.2 or so) where the stack trace when an exception is thrown is woefully devoid of details.
The screeshot here illustrates one such case; in fact, this scenario at least has SOME context (it shows me that it happened in the JKArray class), where many times I get nothing but "internal" stack items (just 2-3 entries in the thread, none of which reside in user code or anything I can look at). Even in this example, I don't know where the JKArray was allocated or released, so I have no idea what instance or where the problem is.
Thoughts:
I've tried adding a generic "on exception" breakpoint
There is some minor information available in the output; in this case: " malloc: * error for object 0x10e18120: pointer being freed was not allocated * set a breakpoint in malloc_error_break to debug". Doing this doesn't get me any further, though, since the breakpoint gets hit in the same stack as the exception...
I've tried switching to the other debugger
I've tried using my own custom exception handler
I've tried using the Profiler to look for leaks. There are no leaks that I can find.
No matter what I do, I can't seem to isolate the issues plaguing my app. Furthermore, the issues do not seem to be exactly the same each time, likely due to the high amount of concurrency in my app... so I'm left without a good way to fix the problems.
Edit: in the case of this particular exception, I did end up finding the cause. I had attempted to [release] and object that was [autoreleased]d. However, all of this was happening within my code; I can't understand why XCode would not give me a decent stack trace to help me find the problem, rather than forcing me to hunt through my whole app...
Sometimes it is impossible to pinpoint the real problem, because the issue that causes the symptom has happened much earlier.
Your issue provides a great example: when you release your object, cocoa has no idea that you've done anything wrong: you are releasing an object that you own, this is precisely what you should be doing, so there's no red flags. The code that leads to a breakdown is executed well after your method has finished, and gave the control back to the run loop. It is at this point that the run loop gets around to draining its autorelease pool, causing the second deallocation. All it knows at this point, however, is that the run loop has made an invalid deallocation, not your code. By the time the error happens the culprit is safely off the stack (and off the hook), so there is nothing else Xcode can report back to you.
A solution to problems like this is to profile your memory use: the profiler should catch issues like that, and pinpoint the places where they happen.
It goes without saying that switching to automatic reference counting will save you lots of troubles in the memory management department.

Track down out-of-bounds access on iPhone

I work on an average (~ 20k lines of code, Objective-C mixed with C++), and I am figthing to hunt down an EXC_BAD_ACCESS error.
I have tried all the common techniques (like enabling NSZombie, guard edges,etc.) So far, I have ruled out the possibility to access a released object, and the double-free error.
It seems that something writes on a memory space where it shouldn't. But, as many memory errors, it's not happening all the time, and it's not crashing always in the same place.
(Sometimes I receive the "object was modified after being freed" message).
Sometimes, the overwritten memory belongs to the allocator, and it crashes on malloc, or on free().
And, of course, some changes in the app may influence the bug's behaviour - if I try to comment out parts of the code, the error appears less often, so it's more difficult to find it.
Finally, I have been looking into using valgrind, but it seems that all those who used it worked on the simulator. but my code must run on the actual device (some code is ARM-specific)
Are there any general tips on how to debug such errors?
Note: The app involves video processing, so the amount of memory used is fairly large.
There are some special tools available on the XCode. You could try to use them in order to analyse your code.
http://developer.apple.com/library/mac/#featuredarticles/StaticAnalysis/index.html
It will produce some warning in case of invalid objects usage so it could help you to find a problem.
If you feel that the C++ code is causing the issue you could copy the C++ out of your iPhone project and create a Mac project. With this you could set up various stress tests. And, you should be able to use valgrind as well.

Iphone random crash issue

Recently my iphone project comes to the end, but suffer some random crash during app running, and the call stack is always located in COCOA library, tough issue, don't know how to deal with it, for some cases I even suspect that is it apple's defect?
My questions.
For those random crash issue with few reproduce rate, how do you guys handle it? Any method to help to increase reproducible rate?
How to fix these crashes located in COCOA library? How to find more clues?
Any idea or discussion will be appreciated, thanks in advance.
If the app crashes in the COCOA code it does not mean that COCOA code is wrong - much more likely you fed some invalid data to it (for example nil where it does not supposed to be). If it's happening randomly there might be some multithreading concurrency behind or some of your objects become (auto)released too early, etc. You have to carefully analyze your code which operates with the COCOA classes where your crash happens, or try memory management debugging as suggested by other answerers.
Generally, I don't start thinking that is COCOA the problem. It happens, but most cases the fault is ours.
When this kind of crashes happens the first thing to do is to run the static Analyzer, sometimes it's just a retain/release problem.
If you're using ARC, skip this part and start creating an Exception Breakpoint (search 'To add an exception breakpoint...' in linked guide). The exception breakpoint helps to have a more detailed crash log when an exception is thrown.
The third step is using Instruments, looking for waster memory, leaks and any other form of memory drain. How to use Instruments is deeply explained in a couple of WWDC videos.
Enable NSZombie flag.
project(On Top LeftCorner of xcode)>Diagnostics>enable zombie objects
It will lte u know where ur code is crashing ..find it fix it

Thread 1: Program received signal : "EXC_BAD_ACCESS"

I am currently programming a iPhone-app for my maturity research. But there is an behavior I don't understand: Sometimes when i compile my project there is:
Thread 1: Program received signal : "EXC_BAD_ACCESS".
But when I compile the same code a second, or a third time the code just runs fine and i can't get why. I use some MonteCarloSimulation but when it fails it fails executing one of the first 100 simulations. But when every thing runs fine it executes 1000000 simulations without an error.. Really strange isn't it?
Do you have any idea? Can this be an issue of Xcode or arc?
All other things just work perfect.
Do you have to get any further information? I can also send you my code as an email.
This usually means you're trying to access an object that has already been deallocated.
In order to debug these things, Objective C uses something called "NSZombie" that will keep those objects around so you can at least see what it is that's trying to be called. See this question for some details on how to use it.
This is typically caused by accessing some memory that's been corrupted, chances are you have a reference to an object which has been deleted. A lot of the time you may find that the memory where the object was located has not yet been overwritten, so when you attempt to access that memory your data is still intact and there is no problem, hence it working some of the time.
Another scenario would be that you've got some code writing into memory using a bad reference, so you're writing into an area you shouldn't be. Depending on the memory layout when the program starts, this could have no effect some of the time but cause something catastrophic at other times.

iPhone application is crashing and not leaving behind a .crash log file

I'm working on catching a seriously insidious bug that's happening in my code. The problem is, the bug is completely random and can happen either 9 minutes into the application's runtime or 30 minutes. I've gone ahead and added the fabulous PLCrashReporter to my project (http://code.google.com/p/plcrashreporter) and that works fine for trivial bugs. Also, when I'm in doubt, I will navigate to the crash logs found in ~/Library/Logs/CrashReporter/MobileDevice/ and run symbolicatecrash on the crash log. This + GDB will eventually catch any bug, except for the one I'm facing now.
Apparently the nature of this bug is preventing even Apple's crash logs to be properly written to storage. This shows when I sync my iPhone or iPod Touch with iTunes and run symbolicatecrash on my app:
sf$ symbolicatecrash foo.crash
No crash report version in foo.crash at /usr/local/bin/symbolicatecrash line 741.
It might be that my application is not leaving a crash report at all, and exiting due to memory issues. I do indeed see the applicationWillTerminate: executing my NSLog statement before exiting, in my App Delegate. However, after running the application through ObjectAlloc, my application never reaches > 2.08MB of usage. Although if I'm reading the results proper, I did allocate over 28MB of memory throughout the entire duration of my test run.
Thanks again for everything.
A couple of suggestions:
Make sure that you're not actually calling exit(), returning from main(), or otherwise cleanly exiting anywhere in your code. If your application is just quitting, and not crashing, that obviously won't leave a log.
I think that running the system very rapidly out of memory can sometimes cause your application to crash without leaving a crash log. Run it under Instruments and see what the memory usage over time looks like.
If you have a set of steps that "often" reproduces the problem, try running it under the debugger and poking at it until it does crash. That might be a half-hour well-spent.
Having eliminated the obvious/easy, it's on to the more-obscure. Chances are that you're corrupting your heap or stack somewhere along the way, via a buffer overrun, re-using an invalid pointer, etc, etc. Here are some things to try:
Try running with NSZombieEnabled=YES in the environment variables. This will help you find re-use of freed objects. It does have an enormous impact on memory usage though, so it may not be applicable for everyone. Here's an Apple article dealing with NSZombie (among other things).
When running in the iPhone Simulator, use the "Simulate Memory Warning" item in the Hardware menu to force a low-memory condition - this can flush out bugs in that code, which otherwise runs at unpredictable times.
Last but not least, do a search through your code for everywhere that you use low-level C memory manipulation functions - malloc, calloc, realloc, memcpy, strcpy,strncpy, etc - and make absolutely sure that the buffer sizes are appropriate.