GeometryReader crash

Hi,

One tester has faced the below crash when leaving a screen that has a progress bar item, apparently the geometry.size.width check is where it crashed but I don't understand why could that line cause it or if I could add some check to avoid it. The error can't be reproduced in the tester's device or any other, it looks like an issolated crash probably due to some internal swiftui thing that I can't figure out.

The app pages are inside an UITabBarController.


//
//  ProgressBarItem.swift
//  Sellispace
//
//  Created by Marc Biosca on 5/4/20.
//  Copyright © 2020 Marc Biosca. All rights reserved.
//

import SwiftUI

struct ProgressBarItem: View {
    @ObservedObject var model: WebViewObservable
    let uuid: String
    
    var body: some View {
        GeometryReader { geometry in
            VStack {
                ZStack(alignment: .trailing) {
                    ZStack (alignment: .leading) {
                        Rectangle()
                            .frame(width: geometry.size.width)
                            .foregroundColor(ThemeColors.accentColor)
                            .opacity(0.5)
                        
                        ZStack (alignment: .trailing) {
                            Rectangle()
                                .frame(width: geometry.size.width * CGFloat(self.model.estimatedProgress))
                                .foregroundColor(self.model.errorTriggered ? ThemeColors.errorCancelColor : self.model.estimatedProgress > 0.9 ? ThemeColors.OkColor : ThemeColors.alternativeAccentColor)
                            
                            Image("Selli_intro")
                                .fit()
                                .padding(.trailing, self.model.estimatedProgress > 0.9 ? 25 : 5)
                                .padding(.leading, self.model.estimatedProgress < 0.2 ? 5 : 5)
                                .padding(.vertical, 1)
                        }
                        
                        HStack {
                            Spacer()
                            
                            Text("\(StringValues.loaded)\((self.model.estimatedProgress * 100).format(decimals: self.model.estimatedProgress == 1 ? "0" : "2"))%")
                                .comment(foregroundColor: Color.white)
                               
                            Spacer()
                        }
                        .animation(.none)
                    }
                    .cornerRadius(5)
                
                    Button(action: {
                        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "refresh-\(self.uuid)"), object: nil)
                    }) {
                        Image(systemName: "arrow.clockwise")
                            .fit()
                            .padding(.vertical, 3)
                            .padding(.trailing, 5)
                            .foregroundColor(Color.white)
                    }
                }
            }
        }
        .padding(5)
    }
}

struct ProgressBarItem_Preview: PreviewProvider {
    static var previews: some View {
        NavigationView {
            ProgressBarItem(model: WebViewObservable(), uuid: "test")
                .navigationBarTitle("Preview", displayMode: .inline)
        }
        //.environment(\.colorScheme, .dark)
    }
}

Crash:

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Triggered by Thread:  0


Thread 0 name:
Thread 0 Crashed:
0   libsystem_kernel.dylib         0x00000001abbf5d88 __pthread_kill + 8
1   libsystem_pthread.dylib       0x00000001abb0e1e8 pthread_kill$VARIANT$mp + 136 (pthread.c:1458)
2   libsystem_c.dylib             0x00000001aba61644 abort + 100 (abort.c:110)
3   AttributeGraph                 0x00000001d740bd90 AG::precondition_failure(char const*, ...) + 188 (ag-util.cc:38)
4   AttributeGraph                 0x00000001d73e2540 AG::Graph::input_value_ref_slow(unsigned int, unsigned int, AGTypeID, bool*) + 476 (ag-graph.cc:842)
5   SwiftUI                       0x00000001e2b0877c RootGeometry.update(context:) + 112 (<compiler-generated>:0)
6   SwiftUI                       0x00000001e2b0c220 partial apply for protocol witness for static UntypedAttribute._update(_:graph:attribute:) in con... + 24 (<compiler-generated>:0)
7   AttributeGraph                 0x00000001d73de9fc AG::Graph::UpdateStack::update() + 440 (ag-closure.h:104)
8   AttributeGraph                 0x00000001d73deeb4 AG::Graph::update_attribute(unsigned int, bool) + 372 (ag-graph-update.cc:399)
9   AttributeGraph                 0x00000001d73e2438 AG::Graph::input_value_ref_slow(unsigned int, unsigned int, AGTypeID, bool*) + 212 (ag-graph.cc:866)
10  SwiftUI                       0x00000001e2b95518 _PositionAwareLayoutContext.dimensions.getter + 56 (<compiler-generated>:0)
11  SwiftUI                       0x00000001e2c15418 partial apply for thunk for @callee_guaranteed () -> (@unowned CGSize) + 24 (<compiler-generated>:0)
12  SwiftUI                       0x00000001e2c15834 specialized closure #1 in GeometryProxy.sync<A>(_:) + 92 (GeometryReader.swift:126)
13  SwiftUI                       0x00000001e2c15dac specialized closure #1 in GeometryProxy.sync<A>(_:) + 20 (<compiler-generated>:0)
14  SwiftUI                       0x00000001e2d9a49c ViewRendererHost.updateViewGraph<A>(body:) + 80 (ViewRendererHost.swift:70)
15  SwiftUI                       0x00000001e2c149c8 GeometryProxy.size.getter + 176 (GeometryReader.swift:125)
16  Sellispace                     0x0000000102689cd4 closure #1 in closure #1 in closure #1 in closure #1 in ProgressBarItem.body.getter + 68 (ProgressBarItem.swift:21)
17  Sellispace                     0x00000001026899b0 closure #1 in closure #1 in closure #1 in ProgressBarItem.body.getter + 448 (ProgressBarItem.swift:0)
18  Sellispace                     0x0000000102689744 closure #1 in ProgressBarItem.body.getter + 400 (<compiler-generated>:0)
19  Sellispace                     0x000000010268a8e8 partial apply for closure #1 in ProgressBarItem.body.getter + 20 (<compiler-generated>:0)
20  SwiftUI                       0x00000001e2c1515c GeometryReader.Child.update(context:) + 396 (GeometryReader.swift:79)
21  SwiftUI                       0x00000001e2c153b4 protocol witness for static UntypedAttribute._update(_:graph:attribute:) in conformance GeometryR... + 36 (<compiler-generated>:0)
22  AttributeGraph                 0x00000001d73f5998 partial apply + 28 (<compiler-generated>:0)
23  AttributeGraph                 0x00000001d73de9fc AG::Graph::UpdateStack::update() + 440 (ag-closure.h:104)
24  AttributeGraph                 0x00000001d73deeb4 AG::Graph::update_attribute(unsigned int, bool) + 372 (ag-graph-update.cc:399)
25  AttributeGraph                 0x00000001d73e3c30 AG::Subgraph::update(unsigned int) + 688 (ag-subgraph.cc:517)
26  SwiftUI                       0x00000001e2b05c84 ViewGraph.runTransaction(in:) + 212 (ViewGraph.swift:716)
27  SwiftUI                       0x00000001e2b05a48 closure #1 in ViewGraph.flushTransactions() + 252 (ViewGraph.swift:612)
28  SwiftUI                       0x00000001e2b056ec ViewGraph.flushTransactions() + 180 (<compiler-generated>:0)
29  SwiftUI                       0x00000001e2da3c24 closure #1 in ViewRendererHost.render(interval:updateDisplayList:) + 220 (ViewRendererHost.swift:140)
30  SwiftUI                       0x00000001e2d9ac5c ViewRendererHost.render(interval:updateDisplayList:) + 316 (ViewRendererHost.swift:132)
31  SwiftUI                       0x00000001e2ec0d78 _UIHostingView.layoutSubviews() + 160 (UIHostingView.swift:1377)
32  SwiftUI                       0x00000001e2ec0da4 @objc _UIHostingView.layoutSubviews() + 24 (<compiler-generated>:0)
33  UIKitCore                     0x00000001b0359c7c -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2144 (UIView.m:17176)
34  QuartzCore                     0x00000001b28f34ac -[CALayer layoutSublayers] + 284 (CALayer.mm:9644)
35  QuartzCore                     0x00000001b28f9604 CA::Layer::layout_if_needed(CA::Transaction*) + 468 (CALayer.mm:9518)
36  QuartzCore                     0x00000001b2904148 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 140 (CALayer.mm:2468)
37  QuartzCore                     0x00000001b284ce34 CA::Context::commit_transaction(CA::Transaction*, double) + 296 (CAContextInternal.mm:1992)
38  QuartzCore                     0x00000001b28767c4 CA::Transaction::commit() + 676 (CATransactionInternal.mm:438)
39  QuartzCore                     0x00000001b28771d8 CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 92 (CATransactionInternal.mm:890)
40  CoreFoundation                 0x00000001abd7dfb8 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32 (CFRunLoop.c:1758)
41  CoreFoundation                 0x00000001abd78eac __CFRunLoopDoObservers + 420 (CFRunLoop.c:1868)
42  CoreFoundation                 0x00000001abd79328 __CFRunLoopRun + 968 (CFRunLoop.c:2910)
43  CoreFoundation                 0x00000001abd78c34 CFRunLoopRunSpecific + 424 (CFRunLoop.c:3192)
44  GraphicsServices               0x00000001b5ec238c GSEventRunModal + 160 (GSEvent.c:2246)
45  UIKitCore                     0x00000001afeab22c UIApplicationMain + 1932 (UIApplication.m:4820)
46  Sellispace                     0x000000010262d680 main + 68 (CoreManager.swift:15)
47  libdyld.dylib                 0x00000001abc00800 start + 4

Replies

We're seeing a _very_ similar crash. Though it doesn't reproduce 100% of the time, it happens quite regularly.


Exception Type:        EXC_CRASH (SIGABRT)
Exception Codes:       0x0000000000000000, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY


Application Specific Information:
abort() called
CoreSimulator 704.12.2 - Device: iPhone 11 (2CFE4E5E-4E50-4F44-A315-7E722C65F4AC) - Runtime: iOS 13.5 (17F61) - DeviceType: iPhone 11
AttributeGraph precondition failure: invalid input index: 2.



Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib         0x00007fff51b617fa __pthread_kill + 10
1   libsystem_pthread.dylib       0x00007fff51c0cbc1 pthread_kill + 432
2   libsystem_c.dylib             0x00007fff51af0b7c abort + 120
3   com.apple.AttributeGraph       0x00007fff2fc8ce40 AG::precondition_failure(char const*, ...) + 273
4   com.apple.AttributeGraph       0x00007fff2fc64846 AG::Graph::input_value_ref_slow(unsigned int, unsigned int, AGTypeID, bool*) + 490
5   com.apple.SwiftUI             0x00007fff2c538ab1 RootGeometry.update(context:) + 97
6   com.apple.SwiftUI             0x00007fff2c53c4d8 partial apply for protocol witness for static UntypedAttribute._update(_:graph:attribute:) in conformance RootGeometry + 24
7   com.apple.AttributeGraph       0x00007fff2fc60d3d AG::Graph::UpdateStack::update() + 455
8   com.apple.AttributeGraph       0x00007fff2fc6124b AG::Graph::update_attribute(unsigned int, bool) + 373
9   com.apple.AttributeGraph       0x00007fff2fc64723 AG::Graph::input_value_ref_slow(unsigned int, unsigned int, AGTypeID, bool*) + 199
10  com.apple.SwiftUI             0x00007fff2c5ceb92 _PositionAwareLayoutContext.dimensions.getter + 50
11  com.apple.SwiftUI             0x00007fff2c65c164 partial apply for thunk for @callee_guaranteed () -> (@unowned CGSize) + 20
12  com.apple.SwiftUI             0x00007fff2c65c582 specialized closure #1 in GeometryProxy.sync<A>(_:) + 66
13  com.apple.SwiftUI             0x00007fff2c65ca7e specialized closure #1 in GeometryProxy.sync<A>(_:) + 14
14  com.apple.SwiftUI             0x00007fff2c65caa1 partial apply for specialized  + 17
15  com.apple.SwiftUI             0x00007fff2c80ee27 ViewRendererHost.updateViewGraph<A>(body:) + 71
16  com.apple.SwiftUI             0x00007fff2c80eb23 protocol witness for ViewGraphDelegate.updateViewGraph<A>(body:) in conformance _UIHostingView<A1> + 19
17  com.apple.SwiftUI             0x00007fff2c65b5ca GeometryProxy.size.getter + 186
18  com.apple.SwiftUI             0x00007fff2c65c3e5 GeometryProxy.frame(in:) + 21
19  com.myco.UI                  0x0000000103bfe695 closure #1 in FramePreferenceViewModifier.body(content:) + 149 (FramePreference.swift:54)
20  com.myco.UI                  0x0000000103bffb3c partial apply for closure #1 in FramePreferenceViewModifier.body(content:) + 12
21  com.apple.SwiftUI             0x00007fff2c65be76 GeometryReader.Child.update(context:) + 390
22  com.apple.SwiftUI             0x00007fff2c65c0b0 protocol witness for static UntypedAttribute._update(_:graph:attribute:) in conformance GeometryReader<A>.Child + 32
23  com.apple.AttributeGraph       0x00007fff2fc78309 partial apply + 25
24  com.apple.AttributeGraph       0x00007fff2fc60d3d AG::Graph::UpdateStack::update() + 455
25  com.apple.AttributeGraph       0x00007fff2fc6124b AG::Graph::update_attribute(unsigned int, bool) + 373
26  com.apple.AttributeGraph       0x00007fff2fc65d53 AG::Subgraph::update(unsigned int) + 729
27  com.apple.SwiftUI             0x00007fff2c5359e0 ViewGraph.runTransaction(in:) + 224
28  com.apple.SwiftUI             0x00007fff2c535796 closure #1 in ViewGraph.flushTransactions() + 262
29  com.apple.SwiftUI             0x00007fff2c535475 ViewGraph.flushTransactions() + 213
30  com.apple.SwiftUI             0x00007fff2c819ac3 closure #1 in ViewRendererHost.render(interval:updateDisplayList:) + 179
31  com.apple.SwiftUI             0x00007fff2c80f785 ViewRendererHost.render(interval:updateDisplayList:) + 373
32  com.apple.SwiftUI             0x00007fff2c96f9e2 _UIHostingView.layoutSubviews() + 226
33  com.apple.SwiftUI             0x00007fff2c96fa05 @objc _UIHostingView.layoutSubviews() + 21
34  com.apple.UIKitCore           0x00007fff49193678 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2478
35  com.apple.QuartzCore           0x00007fff2b4c6398 -[CALayer layoutSublayers] + 255
36  com.apple.QuartzCore           0x00007fff2b4cc523 CA::Layer::layout_if_needed(CA::Transaction*) + 523
37  com.apple.QuartzCore           0x00007fff2b4d7bba CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 80
38  com.apple.QuartzCore           0x00007fff2b420c04 CA::Context::commit_transaction(CA::Transaction*, double) + 324
39  com.apple.QuartzCore           0x00007fff2b4545ef CA::Transaction::commit() + 649
40  com.apple.SwiftUI             0x00007fff2c96fb14 _UIHostingView.displayLinkTimer(timestamp:) + 244
41  com.apple.SwiftUI             0x00007fff2c45343d DisplayLink.displayLinkTimer(_:) + 77
42  com.apple.SwiftUI             0x00007fff2c453496 @objc DisplayLink.displayLinkTimer(_:) + 38
43  com.apple.QuartzCore           0x00007fff2b3814c6 CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 538
44  com.apple.QuartzCore           0x00007fff2b4588f0 display_timer_callback(__CFMachPort*, void*, long, void*) + 299
45  com.apple.CoreFoundation       0x00007fff23d6187d __CFMachPortPerform + 157
46  com.apple.CoreFoundation       0x00007fff23da14e9 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
47  com.apple.CoreFoundation       0x00007fff23da0ae8 __CFRunLoopDoSource1 + 472
48  com.apple.CoreFoundation       0x00007fff23d9b514 __CFRunLoopRun + 2228
49  com.apple.CoreFoundation       0x00007fff23d9a944 CFRunLoopRunSpecific + 404
50  com.apple.GraphicsServices     0x00007fff38ba6c1a GSEventRunModal + 139
51  com.apple.UIKitCore           0x00007fff48c8b9ec UIApplicationMain + 1605
52  com.myco.myapp                0x0000000100821e28 main + 56 (AppDelegate.swift:14)
53  libdyld.dylib                 0x00007fff51a231fd start + 1

I was able to create a reliable reproducer of the precondition failure. The magic combination seems to be a SwiftUI List in a Tab, where each element in the List utilizes a GeometryReader to read the GeometryProxy's frame. Also, the List rows are populated in "onAppear". Simply switching to a tab containing a List configured as described causes the precondition failure.


I've submitted FB7733658.

I'm seeing the same issue with a very similar setup of Geometry Reader inside a LazyVGrid in a Section inside a Form for a view wrapped by a NavigationView in a TabView. A onAppear is also used but only to fetch data that the view inside the GeometryReader will then receive (onAppear doesn't set data by itself).

The method that fails for me is:

Code Block
AttributeGraph: AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 176

We recently encountered this crash on iOS 14, but not iOS 15. Thanks to djehrlich's pointer, we were able to narrow it down to the same situation: GeometryReader inside List inside Tab.

The crash only happened on archive builds, not when attempting to build from Xcode (debug or release). We were able to reproduce the crash by using ad hoc builds from our CD server and narrowed it down to when we introduced the GeometryReader inside List.

Curiously, it seems that Xcode 13.3 may have fixed the crash. The builds made with Xcode 13.2.1 crashed, whereas the builds made with Xcode 13.3 no longer crash.