Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[Bug] Layout.ResolveLayoutChanges throwing collection was modified exception on iOS #15003

Open
JohnHDev opened this issue Dec 28, 2021 · 8 comments
Labels
p/iOS 🍎 s/needs-info ❓ A question has been asked that requires an answer before work can continue on this issue. s/needs-repro ❔ This reported issue doesn't include a sample project reproducing the issue. Please provide one. s/unverified New report that has yet to be verified t/bug 🐛

Comments

@JohnHDev
Copy link

JohnHDev commented Dec 28, 2021

Description

In AppCenter crash reporting I am seeing reports of the following exception:
SIGABRT: Collection was modified; enumeration operation may not execute.

Stacktrace:
List1+Enumerator[T].MoveNextRare () (wrapper other) System.Object.gsharedvt_in() (wrapper other) System.Object.gsharedvt_out() List1+Enumerator[T].MoveNext ()
Layout.ResolveLayoutChanges ()
VisualElementRenderer`1[TElement].ResolveLayoutChanges ()

Steps to Reproduce

Unable to reproduce locally

Expected Behavior

Actual Behavior

Basic Information

  • Version with issue: XF 5.0
  • Last known good version: Unknown
  • Platform Target Frameworks:
    • iOS:
  • NuGet Packages:
  • Affected Devices:

Environment

Show/Hide Visual Studio info

Build Logs

Screenshots

Reproduction Link

Workaround

None

@JohnHDev JohnHDev added s/unverified New report that has yet to be verified t/bug 🐛 labels Dec 28, 2021
@jfversluis jfversluis added p/iOS 🍎 s/needs-info ❓ A question has been asked that requires an answer before work can continue on this issue. s/needs-repro ❔ This reported issue doesn't include a sample project reproducing the issue. Please provide one. labels Dec 30, 2021
@jfversluis
Copy link
Member

Thanks for the report! Any new or additional information is much appreciated, this is not much to go on unfortunately

@JohnHDev
Copy link
Author

@jfversluis sorry, I haven't been able to replicate locally at all, its just the errors Im seeing in AppCenter diagnostics.
Looking at the XF source, it looks to be a safe iteration with the copy and new list, only thing I can suggest is iterating a copy instead of the original list? That way, if anything still has a reference to the original list it won't matter.

@JohnHDev
Copy link
Author

Ive just pulled out the full stack trace on this from AppCenter:
List1+Enumerator[T].MoveNextRare () (wrapper other) System.Object.gsharedvt_in() (wrapper other) System.Object.gsharedvt_out() List1+Enumerator[T].MoveNext ()
Layout.ResolveLayoutChanges ()
VisualElementRenderer1[TElement].ResolveLayoutChanges () VisualElementRenderer1[TElement].LayoutSubviews ()
FrameRenderer.LayoutSubviews ()
(wrapper managed-to-native) UIKit.UIApplication.UIApplicationMain(int,string[],intptr,intptr)
UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName)
Application.Main (System.String[] args)

Any thoughts on how you might resolve this?

@JohnHDev
Copy link
Author

@jfversluis Here is the full stack from the raw logs in AppCenter:

Xamarin Exception Stack:
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.Collections.Generic.List1+Enumerator[T].MoveNextRare () <0x104a5e250 + 0x000c3> in <25bf495f7d6b4944aa395b3ab5293479#ae002c96de94f0526c38425284ae2890>:0 at (wrapper other) System.Object.gsharedvt_in() at (wrapper other) System.Object.gsharedvt_out() at System.Collections.Generic.List1+Enumerator[T].MoveNext () <0x104a5e080 + 0x001a3> in <25bf495f7d6b4944aa395b3ab5293479#ae002c96de94f0526c38425284ae2890>:0
at Xamarin.Forms.Layout.ResolveLayoutChanges () <0x1062edd40 + 0x000e7> in <361de4fd2138410a8d727d37bccf8e01#ae002c96de94f0526c38425284ae2890>:0
at Xamarin.Forms.Platform.iOS.VisualElementRenderer1[TElement].ResolveLayoutChanges () <0x10658acf0 + 0x00067> in <b051e9cbd93541f597d16d8eff25e3d4#ae002c96de94f0526c38425284ae2890>:0 at Xamarin.Forms.Platform.iOS.VisualElementRenderer1[TElement].LayoutSubviews () <0x10658adc4 + 0x0001b> in <b051e9cbd93541f597d16d8eff25e3d4#ae002c96de94f0526c38425284ae2890>:0
at (wrapper managed-to-native) UIKit.UIApplication.UIApplicationMain(int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) <0x105733f1c + 0x00063> in <5b08e01cb6df409eb2fea153e6177e5d#ae002c96de94f0526c38425284ae2890>:0
at myAppNameHere.iOS.Application.Main (System.String[] args) <0x10499ad7c + 0x00033> in <03701bc38b1a42dcaecc3806339cbf1b#ae002c96de94f0526c38425284ae2890>:0

@jfversluis
Copy link
Member

jfversluis commented Feb 18, 2022

That seems helpful, thanks! Trying to pinpoint the origin, but not really seeing any iteration going on in that part of the code... Are you calling any layout methods yourself?

Need to go one layer deeper. Seems the origin is here then, but why! It already copies the collection so it shouldn't be changed while this is running

@JohnHDev
Copy link
Author

Yeah as I mentioned in my first reply, it seemed like a safe iteration on the copy (in ResolveLayoutChanges), unless something else still has a reference to it. If 2 parts of the code both take references of the same list at the same time, this could happen. There are other, possibly safer ways of doing this, maybe perform a new list with the contents and iterate that. I can see you are trying to be lock free here for speed.

@JohnHDev
Copy link
Author

It already copies the collection so it shouldn't be changed while this is running

@jfversluis Well, technically it's not a copy, it's the original list. But still I don't see how this error could occur, but it quite clearly does. This is now the number 1 crash report for us in AppCenter.

@JohnHDev
Copy link
Author

@jfversluis I have managed to work around the problem when the layout is a Frame (custom renderer, wrap in a try catch and run it again), but not for VisualElementRenderer.

More info though, I believe this is due to an animation. I spotted this in the thread that crashed:
15 UIKitCore 0x000000018c9d8844 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2588
16 QuartzCore 0x000000018e14e1c0 CA::Layer::layout_if_needed(CA::Transaction*) + 528
17 QuartzCore 0x000000018e1405fc CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 132
18 QuartzCore 0x000000018e154f70 CA::Context::commit_transaction(CA::Transaction*, double, double*) + 448
19 QuartzCore 0x000000018e15de78 CA::Transaction::commit() + 700
20 UIKitCore 0x000000018cb9f6e8 __34-[UIApplication _firstCommitBlock]_block_invoke_2 + 40
21 CoreFoundation 0x000000018a44f0e4 CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK + 24
22 CoreFoundation 0x000000018a450040 __CFRunLoopDoBlocks + 408
23 CoreFoundation 0x000000018a3e7b60 __CFRunLoopRun + 844
24 CoreFoundation 0x000000018a3fb6b8 CFRunLoopRunSpecific + 596
25 GraphicsServices 0x00000001a6495374 GSEventRunModal + 160
26 UIKitCore 0x000000018cd60e88 -[UIApplication _run] + 1096
27 UIKitCore 0x000000018cae25ec UIApplicationMain + 360

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
p/iOS 🍎 s/needs-info ❓ A question has been asked that requires an answer before work can continue on this issue. s/needs-repro ❔ This reported issue doesn't include a sample project reproducing the issue. Please provide one. s/unverified New report that has yet to be verified t/bug 🐛
Projects
None yet
Development

No branches or pull requests

2 participants