SwiftUI internal rendering engine crash (attempt to read deallocated ViewGraph reference)

Originator:defagos
Number:rdar://FB8935555 Date Originated:Dec 10, 2020
Status:Closed Resolved:
Product:tvOS Product Version:14
Classification:Crash Reproducible:
 
Description of the problem:

My Apple TV application is written in SwiftUI 2nd gen (tvOS 14). When presenting a view and dismissing it fast, my app crashes with the following stack trace (full stack trace provided as attachment):

0   libsystem_kernel.dylib        	0x000000018449284c __pthread_kill + 8
1   libsystem_pthread.dylib       	0x0000000184516c30 pthread_kill + 212 (pthread.c:1388)
2   libsystem_c.dylib             	0x00000001843fe8ac abort + 100 (abort.c:110)
3   libswiftCore.dylib            	0x000000019aa2e108 swift::fatalError(unsigned int, char const*, ...) + 56 (Errors.cpp:393)
4   libswiftCore.dylib            	0x000000019aa2e258 swift::swift_abortRetainUnowned(void const*) + 52 (Errors.cpp:456)
5   libswiftCore.dylib            	0x000000019aa2fd34 swift_unownedRetainStrong + 168 (HeapObject.cpp:590)
6   SwiftUI                       	0x00000001a859e7a8 ViewRendererHost.enclosingHosts.getter + 84 (ViewRendererHost.swift:308)
7   SwiftUI                       	0x00000001a859c78c ViewRendererHost.performExternalUpdate(_:) + 52 (ViewRendererHost.swift:320)
8   SwiftUI                       	0x00000001a833ea80 closure #4 in closure #1 in PlatformViewChild.updateValue() + 68 (PlatformViewRepresentable.swift:401)
9   SwiftUI                       	0x00000001a833dc54 closure #1 in PlatformViewChild.updateValue() + 2368 (<compiler-generated>:0)
10  SwiftUI                       	0x00000001a833d018 PlatformViewChild.updateValue() + 584 (PlatformViewRepresentable.swift:306)
11  SwiftUI                       	0x00000001a8179e04 partial apply for implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 28 (<compiler-generated>:0)
... 

The call stack only contains internal SwiftUI rendering API calls, and the following message is logged to the console:  "Attempted to read an unowned reference but object <address> was already deallocated".

If I have a look at the Xcode memory debugger at the time of the crash (attached screenshot) I can see that the type of the already deallocated object is ViewGraph. I don't know SwiftUI internals, but it appears some object might still be referencing the view graph (or a subtree thereof), probably discarded at the same time view is dismissed.

Though my app runs on tvOS, it is likely this issue affects other platforms as well (I don't see any tvOS specifics here).

Here are some additional implementation details, but I cannot say if they might explain why the crash occurs:

- I am using UIViewController modal presentation and dismissal of a UIHostingController, not SwiftUI modal presentation.
- One of the presented views wraps a UIKit view (UICollectionView) using UIViewRepresentable.

Environment:

- Crash reproduced with tvOS 14.0, 14.2 and 14.3 beta.
- Reproduced with Apple TV HD (4th gen) and Apple TV 4K (5th gen).


How to reproduce the issue:

There is no easy way to create a simple demo with which this can be reproduced, I am afraid. You can still contact me if this can help you (my project is open source so it is always possible to reproduce and discuss the crash together).


Expected behavior:

SwiftUI does not crash internally.


Actual behavior:

SwiftUI sometimes crashes internally.

Comments

Fixed

Fixed in tvOS 15


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!