UPDATE This crash seems to have stopped occurring since iOS 7.1 was release. At this time (4th April) I haven't seen any occurrences on iOS 7.1 when I was seeing it more about weekly on iOS 7.0x. Several other crash types have also not been observed on iOS 7.1 although two instances of a different crash have been seen.
Most software crashes sometimes and unfortunately this includes Fast Lists. At the moment I have records of 12 crashes in the latest version (2.04) that was released about a month ago (18th Feb). On many occasions crashes are clearly caused within the software I have developed whether due to my mistake or the libraries (both Apple and 3rd party) that I use having bugs and not and not behaving as documented. This post is about several crash reports that appear to be occurring deep within Apple's code (although quite possibly due to my own incorrect software), it includes the crash reports very slightly redacted and what I have currently deduced about the cause.
I think the general interest in this post for non-developers will be pretty close to zero.
There are several reasons for this post, firstly it is an exercise in rubber duck debugging in which by explaining the problem to someone (real or pretend) you can sometimes develop a deeper understanding and solve the problem. Secondly by putting some of these issues on the public web Google, DuckDuckGo and other search engines may index this and help me link up with others suffering the same and similar issues and thirdly it will show and explain the data Human Friendly gathers when there is a crash to reassure customers that it isn't exposing private information.
[UIPopoverController _completionBlockForDismissalWhenNotifyingDelegate:]_block_invoke + 327
This crash has happened and been reported on at least 6 occasions on Fast Lists versions 2.03 and 2.04 at least iOS versions 7.02, 7.04, 7.06 on iPad only (which isn't that surprising because popovers are only normally used on the iPad.
The full symbolicated crash report is available if you are interested but I think that the key bits are here:
The above may be complete nonsense to you if you are not a developer and if that is the case you may want to find something completely different to read. If you are an iOS developer it should be pretty familiar but there is a good basic introduction here and an excellent dive into deep analysis of an issue by the main developer of PLCrashReporter that goes beyond my capabilities and those are the resources to learn from.
From this report you can see the main information gathered. The only data removed is a unique ID generated for the device sending the report so that I can identify if a single device is having multiple issues or if crashes are coming from different devices. I think it is unique within Fast Lists and not available for other puposes but I have supressed in anyway.
Regarding the crash itself you can see that it had an access error (SEGV_ACCERR) that crashed thread 0. This probably means it accessed memory that had been deallocated (or not allocated at all) although it doesn't tell us why. It does tell us to focus on thread 0 whose callstack is included.
Callstack
This shows the nested functions/methods that were being called at the time of the crash, I'll refer to them by the stack frame numbers (rising sequentially at the left). Stack frame 0 is where the execution actually was, stack frame 1 where stack frame 0 was called from, stack frame 2 where stackframe 1 was called from and so on until 15 which was the initial call that launched the application and 14 which is the 'main' method.
One thing to note is that apart from the stack frame 14 (main) none of the methods in the stack actually in Fast List's own code, they are all in Apple provided libraries that are standard in iOS. This doesn't however mean that the blame is Apple's because if Fast Lists provided bad data (or changed good data) that did not meet the requirements of the functions called then this effect could still be seen. Quite often most of the callstack will be library functions particularly on the main thread because the main UI event loop is managed by Apple's libraries that call into the methods you provide when events or changes happen.
In this case the run loop is processing animation callbacks which then trigger a completion callback for the UIPopoverController (_
So we have an access error when making a call from _completionBlockForDismissalWhenNotifyingDelegate to something else. Unfortunately we don't have the source code for this method (or almost all of Apple's libraries) which makes working out exactly what is happening harder.
Inside objc_msgSend the assembly code looks like this:
The register state is:
The exception was "Exception Codes: SEGV_ACCERR at 0xc185af45" which you can see is r9 (0xc185af39) plus the absolute value #12 (decimal) in the instruction "ldrh.w r12, [r9, #12]" that attempt to load a word into r12.
So at this point I know the exact point of the crash but I don't know what object is was trying to load or why it failed to do so. r0 should contain the intended receiver of the message but that address (0x185c0670)was successfully loaded into r9 in the previous instruction.
And this dear reader may be where the trail runs cold. I'm sorry that this is such a brain dump and not very educational. The next thing I plan to describe is the code I use to create and configure the UIPopoverController to see if there is anything obvious there.
On the off chance that somebody with relevent suggestions or a similar crash reads this please get in touch with me, my email address isn't hard to find.
Update - 21st July 2014
I believe that the cause was actually UIAlertView which is implemented as a Popover and leading to the error coming from the UIPopoverController. I think that the delegate objects were being released without being removed from being the delegate of the UIAlertView. The delegate property is an assign not a weak type so the value was not being set to nil.
I have resolved the issue by the delegate object keeping a weak reference to the UIAlertView and calling [alertView setDelegate:nil] in the delegate's dealloc method.
I may write a separate follow up post with more detail at some point.