Core Data crash within a try catch block - ios

I have the following crash log and code to go along with it:
https://gist.github.com/emilevictor/7422ac293eb27b415fb8
I'm a bit confused, as I have wrapped this Core Data code (which creates a new instance in the database) with a try catch block but it is still crashing out occasionally in on release compiled code.
This is on a device which has had its local data wiped and installed from scratch, by the way.
I'm not sure what else to do, I assume that this code might have an issue.

First the try/catch problem. #try/#catch only trap NSExceptions which have been #thrown or -raised. You don't have this kind of exception, you have a segfault. These happen at a much lower level and cannot be trapped in a #try/#catch.
The real problem here is what's going wrong to cause the segfault. Usually this is caused be objects which have been prematurely -dealloced or by notifications being sent to -dealloced observers. I can see from your call stack that the process is in the middle of sending a notification, so my guess it the second type.
Somewhere, you have registered an observer and that observer has gone out of scope (-dealloced) without unregistering itself. I would start by profiling the app for zombies.

Related

Avoiding fatal crashes

I have been debugging an app for a while and am ready to upload it to app store. However, I still get occasional crashes that are hard to duplicate or debug--for example when pushing buttons in weird sequences. If I write these sequences down, I can debug but inevitably it happens when I haven't written it down and these can be difficult to replicate.
I know I need to just call it a day and leave future bug fixes for next release. I have removed all the abort() statements I had in testing. However, occasionally rather than getting a crash that lets you just close the app and reopen, I get one that makes it impossible to open the app without reinstalling. For example, this just happened, with a
'NSGenericException', reason: '*** Collection <__NSCFSet: 0x174a41b90> was mutated while being enumerated.'
This resulted from switching VCs during a background sync to the cloud.
I can live with crashes where you just need to reopen but not with ones that render the app unusable. Are there any guidelines for types of crashes to help you focus on the really fatal ones?
Or is there anything you can do to keep crashes from bricking app?
You should just fix this problem. Since you have this crashlog with that error message, you know which method can raise the problem, so you've got a good head start on fixing it, even if the problem manifests itself inconsistently and/or in a variety of ways.
But the occasional crash may not seem like too much of an inconvenience to you, but it is the quickest way to 1-star reviews and unhappy customers. I suspect you will quickly regret distributing an app with known, easily reproduced crashes.
But, a few observations:
It sounds like your background update process is mutating your model objects used by the main thread.
If possible, I'd suggest being careful to simply do not change any of your model objects in the background thread, but rather populate a local variable and when you're ready to update the UI accordingly, dispatch both the model update and UI refresh to the main thread.
If you cannot do this for some reason, you have to synchronize all interaction of model updates with some mechanism such as locks, GCD serial queue, reader-writer model, etc. This is slightly more complicated approach, but can be done.
I would advise temporarily editing your target's "scheme" and turn on the thread sanitizer:
It may possibly help you identify and more easily reproduce these sorts of problems. And the more easily you can reproduce the problem, the more easily you will be able to fix the issue.
You say:
Or is there anything you can do to keep crashes from bricking app?
It sounds like the "save" operation is somehow leaving the results in persistent storage in an internally inconsistent manner. Any one of the following would help, though I'd suggest you do all three if possible):
At the risk of repeating myself, fix the crash (it's always better to eliminate the source of the problem than try to program around manifestations of the problem);
Depending upon how you're saving your results, you may be able to employ an atomic save operation, so that if it fails half way, it won't leave it in an inconsistent state; we can't advise how you should do that without seeing code snippet illustrating how you're saving the results, but it's often an option;
Make sure that, if the "load" process that reads the persistent storage can fail, that it does so gracefully, rather than crashing; see if you can get it in this state where the app is failing during start-up, and then carefully debug what's going on in the start-up process that is causing the app to fail with this particular set of data in persistent storage. In the "devices" section, there is an option to download the data associated with an app, so you can carefully diagnose what's going on.

EXC_BAD_ACCESS with MKNetworkEngine

I'm using MKNetworkkit to parse XML data to the server. Before Entering into the success block its gets crash with EXC_BAD_ACCESS with out any reason and am already done with NSZombieEnabled like all the stuffs.![Below is the screen shot of where its getting crash.][1][1]: http://i.stack.imgur.com/FL3l9.png
You may find this useful to help debug http://subhb.org/2012/07/02/how-to-debug-exc_bad_access-error/
You will get EXC_BAD_ACCESS error mostly in the following scenarios:
You are trying to access an object that is not initialized.
You are trying to access an object that no longer exists. Either it’s being released or it’s nil. In ARC mode, make sure you take
ownership of the object that you want to use.
You are passing an message to an object that the object doesn’t understand. It can also happen for bad typecast.
Have you tried running breakpoints on your code and stepping through your program line by line and seeing if any of the above match the result?

Is there a way to simulate the process by which iOS releases orphan objects?

I have a popular iOS app, but I get a handful of crash reports that are always on the same line. I can't reproduce the bug for the life of me, but I suspect it has to do with my 3rd-Party library that doesn't use ARC, and so something is getting released when it shouldn't be.
I've tried simulating a memory warning and I've tried taking random globs of memory using malloc, and I can't reproduce the bug. But it happens often enough for many people to email every day and complain about it.
I know that the OS does some "cleanup" that releases objects that need to be auto-released, but is there a way to force this in a simulator?
A message is being sent to a deallocated object.
Either something is trying to talk to a deallocated DBRequest, or DBRequest is trying to talk to a deallocated object.
The most common cause of this is if you do something like:
[DBRequest setNetworkRequestDelegate:self];
DBRequest *myDBRequest = [DBRequest initWithURLRequest:request andInformTarget:self selector:#selector(doSomething)];
You then start some network activity, the user moves to another view, which deallocates self, the network activity finishes, and tries to inform self that it's completed.
Make sure you are calling [myDBRequest cancel]; in 100% of the cases where the object that would be notified is going to be deallocated. The dealloc method is usually a safe place for this.

How can NSLogs cause code to not crash?

I had a rather interesting exc_bad_access crash today. After a lot of digging, I came up with the following information (running in simulator):
If I just ran the code, the app would randomly crash at a random point while loading data into my managed object. From what I could tell, it was always crashing when I loaded data into the managed object -- not on the sections that converted from my JSON dict to data to the object actually used (from strings and NSNulls to ints/floats and nils)
Random crashes are, of course, evil, so I tried to step through the process in the debugger, but that didn't prove practical -- I was processing a LOT of objects, so stepping through them one-by-one just didn't work. So I decided to add some NSLogs to track the process and try to spot a pattern that way.
Instantly solved the crash.
Just one NSLog, anywhere in the process, prevented the crash.
I eventually tracked my way up the stack trace and found the actual issue: I was accessing the managed object in a threaded environment, but NOT from within the associated MOC's performBlockAndWait: method. At that point, the crash was incredibly obvious to me -- I'm shocked I didn't have more issues earlier. I'm willing to bet that between having a 'small' test data set of 2-3 objects and having debug code in there with NSLogs, the error was pretty effectively masked earlier... but the question remains:
Why does an NSLog prevent the app from crashing? How on earth could a piece of code without side effects change the execution of the rest of the app? This makes no sense!
Amazingly enough, this is a fairly common situation: I have seen it more than once when enabling logging in a seemingly unrelated place would instantly solve a timing issue somewhere else.
The reason for this is that NSLog, just like many other output functions, has internal synchronization. There is a mutex somewhere that protects access to the internal buffers of NSLog, either in the NSLog itself or in one of the I/O libraries that it uses. This synchronization enables callers to use NSLog from multiple threads. It is this synchronization that changes the timing of your program, affecting a race condition and ultimately solving a crash.
Why does an NSLog prevent the app from crashing? How on earth could a
piece of code without side effects change the execution of the rest of
the app? This makes no sense!
Indeed this makes a sense. Really.
A single NSLog forces to print something to your console, it takes some fraction of seconds and in between your processing on somethread gets finished and the crash (might be due to un-availability of input is) no-more.
Your error may be due to async call. Your next process starts before finishing previous one. And your next process need data from previos process. NSLog consumes some time.

iOS xcode, Web services, NSURLConnection second call fails

iPad development, iOS 4.3, objective-c, xcode 4.1.
I have created a wrapper class, which is used to call a method on a web service. It works fine when I make the first call, but fails on subsequent calls.
A method in my class, "runMethod::", opens a NSURLConnection and does the call asynchronously, with the wrapper class itself as the NSURLConnection delegate.
I have read somewhere that there's a fault with Android, which keeps a pool of connections. When you try to make a connection a second time it fails because the previous connection has been kept open, despite the code closing it. Hence, I suspect the problem is that the connection remains in the pool, and when I try to make another one it clashes? Maybe xcode has a similar issue?
And the symptoms of the failure are a seemingly random 'bad access' on a random line in one of the delegate selectors, which suggests this has something to do with threading - I understand that HTTP connections operate on their own thread.
I can provide the full wrapper class if need be, but anyone any ideas?
A 'bad access' error simply indicates that you're dereferencing an invalid pointer. This is most often due to improper memory management, such as failing to retain some object. Code would help, but first try the Analyze command in Xcode -- the static analyzer is pretty good at finding memory problems.

Resources