Skip to content

Instantly share code, notes, and snippets.

@brianpartridge
Created February 8, 2016 23:02
Show Gist options
  • Save brianpartridge/df980e8ae9a94a13a8cc to your computer and use it in GitHub Desktop.
Save brianpartridge/df980e8ae9a94a13a8cc to your computer and use it in GitHub Desktop.
Weird Swift crash stack
Crashed: com.apple.main-thread
EXC_BREAKPOINT 0x00000000e7ffdefe
Thread : Crashed: com.apple.main-thread
0 MyApp 0x210ac4 specialized CartTableViewController.tableView(UITableView, titleForDeleteConfirmationButtonForRowAtIndexPath : NSIndexPath) -> String? (CartTableViewController.swift:190)
1 MyApp 0x2106bc specialized CartTableViewController.tableView(UITableView, titleForDeleteConfirmationButtonForRowAtIndexPath : NSIndexPath) -> String? (CartTableViewController.swift:184)
2 MyApp 0x20d990 @objc CartTableViewController.tableView(UITableView, titleForDeleteConfirmationButtonForRowAtIndexPath : NSIndexPath) -> String? (CartTableViewController.swift)
3 UIKit 0x2726acbb -[UITableView _titleForDeleteConfirmationButtonForRowAtIndexPath:] + 146
4 UIKit 0x27392f4f -[UITableView _deleteConfirmationButtonForRowAtIndexPath:] + 102
5 UIKit 0x27393483 -[UITableView _swipeActionButtonsForRowAtIndexPath:] + 726
6 UIKit 0x27393193 -[UITableView _swipeActionButtons] + 90
7 UIKit 0x2726a6c3 __32-[UITableViewCell _beginSwiping]_block_invoke + 178
8 UIKit 0x2706f651 +[UIView(Animation) performWithoutAnimation:] + 72
9 UIKit 0x2726a601 -[UITableViewCell _beginSwiping] + 92
10 UIKit 0x2738feed -[UITableViewWrapperView handleSwipeBeginning:] + 248
11 UIKit 0x275b72fd _UIGestureRecognizerSendTargetActions + 352
12 UIKit 0x2720034f _UIGestureRecognizerSendActions + 170
13 UIKit 0x27092da7 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 578
14 UIKit 0x275b858f ___UIGestureRecognizerUpdate_block_invoke904 + 62
15 UIKit 0x27053d97 _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 298
16 UIKit 0x27050367 _UIGestureRecognizerUpdate + 2902
17 CoreFoundation 0x22ee6f59 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 20
18 CoreFoundation 0x22ee525d __CFRunLoopDoObservers + 280
19 CoreFoundation 0x22ee568f __CFRunLoopRun + 958
20 CoreFoundation 0x22e38bf9 CFRunLoopRunSpecific + 520
21 CoreFoundation 0x22e389e5 CFRunLoopRunInMode + 108
22 GraphicsServices 0x24084ac9 GSEventRunModal + 160
23 UIKit 0x270c8ba1 UIApplicationMain + 144
24 MyApp 0xa7ca7 main (main.m:35)
25 libdispatch.dylib 0x22ae7873 (Missing)
@brianpartridge
Copy link
Author

Failing method is shown 3 times with no recursion and diff line #s. The line numbers correspond to lines in the specified method, but not anything that should fail.

@brianpartridge
Copy link
Author

CartTableViewController is not generic, it subclasses UITableViewController. Can't reproduce so far.

@mattmassicotte
Copy link

So, some thoughts. First one is to keep in mind that Swift is much more like C++ than it is like C or ObjC. It can be extremely hard to guess/understand why your source would result in surprising code generation (inlining, specialization, thunks, etc). I have seem lots of C++ crashes where transformations the compiler does to make it nearly impossible to understand why the final call structure appears like it does. I have not direct evidence Swift does this kind of thing, but I'm going to guess that it probably does. Inlining, for example, can look like unexpected recursion in C and C++.

Now, on to specifics. EXC_BREAKPOINT implies that some code chose to terminate, explicitly. Could there be an implicitly unwrapped optional, a cast, or some other kind of unexpected code path in the general vicinity?

Have you dug into any logging on a per-crash basis? Where possible, some Swift-specific logging is sometimes recorded in crash reports (apples and crashlytics). This logging is, frustratingly, not always present for release builds, but its at least worth checking. Especially if this is a non-release build.

Is this a common crash, or something that has only happened a few times? If it is uncommon (1-2 times), I typically advise people to not even bother investigating. There is probably lower-hanging fruit, and you may be looking at a innocent code path that is just a victim of a different underlying issue.

Do you have any other crashes related to that table controller, the containing view controller, or table view delegate? If so, I'd shift gears to understand that first, since this does look like it could be a victim-crash. Cast a wide net, as often one problem can manifest itself as may different crashes.

Finally, it is always possible that report itself has bad, invalid, or otherwise incorrect. Crash reporting is not perfect. I've spent tons of time comparing Apple reports, Crashlytics reports, and LLDB backtraces where none of them are exactly the same.

@brianpartridge
Copy link
Author

Thanks for the response, Matt.

I've seen a lot of tough C++ stacks too and the inlining/specialization can be rough. Often times I can identify the inlined function calls in Swift even if the line numbers can be off. Your point about inlines looking like recursion is a good explanation. They're definitely easier to identify in ObjC though.

I was looking for unwrapped optionals as well (pretty much our go-to for crash debugging in the project) and while there is one on CartTableViewController.swift:184 there is not one on the line the crashed CartTableViewController.swift:190. 190 is actually a plan old case statement with no operations:

183  override func tableView(tableView: UITableView, titleForDeleteConfirmationButtonForRowAtIndexPath indexPath: NSIndexPath) -> String? {
184      let cartItem = self.dataSource!.sections[indexPath.section][indexPath.row]
185      switch(cartItem) {
186      case .Contact:
187          return NSLocalizedString("Remove", comment: "...")
188      case .LineItem, .Discount:
189          return NSLocalizedString("Delete", comment: "...")
190      case .Tax, .BarcodeSKU:
191          return nil
192      }
193  }

Given that, if the ! was the problem, I would have expected the stack to be 190 followed by 184 or just 184 with 190 never being reached. ¯_(ツ)_/¯

There doesn't appear to be any additional logging with this crash, which was part of a Release build. We attach some user account details through Crashlytics, but don't have any info about what lead up to this. Plus, this crash has only happened once.

I agree that a single crash like this probably isn't worth much time to examine, but it seemed like a strange case that could inform how we interpret other Swift stacks in the future. Thanks again for your feedback, I really appreciate it.

@mattmassicotte
Copy link

You're very welcome! I agree that the dataSource being nil is probably the issue. If you're feeling really curious, you can try manually constructing a case where the dataSource is nil, build in release and see what the debugger says. I'd love to see that too.

@muditjaju
Copy link

I am facing a similar problem. (More details: http://stackoverflow.com/questions/37276942/swift-specialised-crash-on-uicollectionview-cellforitematindexpath)
Did anyone find a reason for the problem ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment