Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Structural change invalidation issue inside a EntityCommandBuffer playback?

Discussion in 'Entity Component System' started by Mockarutan, Aug 26, 2023.

  1. Mockarutan

    Mockarutan

    Joined:
    May 22, 2011
    Posts:
    158
    [Unity 2022.3.0, ECS 1.0.0-pre.15, Burst 1.8.4]
    I have a pretty strange issue that I don't really know where to start looking for.
    They are quite rare and I've only gotten then in the editor so far I think, they have this structure:


    ArgumentException: Attempted to access ComponentTypeHandle<-Some IComponentData-> which has been invalidated by a structural change.
    EntityCommandBuffer was recorded in -Some SystemBase- and played back in Unity.Entities.EndSimulationEntityCommandBufferSystem.


    Three examples of full stack traces:

    Code (CSharp):
    1. ArgumentException: Attempted to access ComponentTypeHandle<Unity.Rendering.HDRPMaterialPropertyEmissiveColor> which has been invalidated by a structural change.
    2. EntityCommandBuffer was recorded in PillarBeastSystem and played back in Unity.Entities.EndSimulationEntityCommandBufferSystem.
    3.   at (wrapper managed-to-native) Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckDeallocateAndThrow_Injected(Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle&)
    4.   at Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckDeallocateAndThrow (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) [0x00000] in <6c9b376c3fca40b787e8c1a2133bf243>:0
    5.   at Unity.Entities.ComponentSafetyHandles.CompleteAllJobsAndInvalidateArrays () [0x00018] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\ComponentSafetyHandles.cs:211
    6.   at Unity.Entities.ComponentDependencyManager.CompleteAllJobsAndInvalidateArrays () [0x00006] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\ComponentDependencyManager.cs:161
    7.   at Unity.Entities.EntityDataAccess.BeforeStructuralChange () [0x0001e] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityDataAccess.cs:424
    8.   at Unity.Entities.EntityDataAccess.BeginStructuralChanges () [0x00008] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityDataAccess.cs:430
    9.   at Unity.Entities.EntityCommandBuffer+PlaybackProcessor.Init (Unity.Entities.EntityDataAccess* entityDataAccess, Unity.Entities.EntityCommandBufferData* data, Unity.Entities.SystemHandle& originSystemHandle) [0x0003b] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityCommandBuffer.cs:3708
    10.   at Unity.Entities.EntityCommandBuffer.PlaybackInternal (Unity.Entities.EntityDataAccess* mgr) [0x0014e] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityCommandBuffer.cs:3279
    11.   at Unity.Entities.EntityCommandBuffer.Playback (Unity.Entities.EntityManager mgr) [0x00000] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityCommandBuffer.cs:3221
    12.   at Unity.Entities.EntityCommandBufferSystem.FlushPendingBuffers (System.Boolean playBack) [0x00097] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityCommandBufferSystem.cs:208
    13.  
    14. Attempted to access ComponentTypeHandle<Unity.Rendering.HDRPMaterialPropertyEmissiveColor> which has been invalidated by a structural change.
    15. EntityCommandBuffer was recorded in BulletHolesSystem and played back in Unity.Entities.EndSimulationEntityCommandBufferSystem.
    16.   at (wrapper managed-to-native) Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckDeallocateAndThrow_Injected(Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle&)
    17.   at Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckDeallocateAndThrow (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) [0x00000] in <6c9b376c3fca40b787e8c1a2133bf243>:0
    18.   at Unity.Entities.ComponentSafetyHandles.CompleteAllJobsAndInvalidateArrays () [0x00018] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\ComponentSafetyHandles.cs:211
    19.   at Unity.Entities.ComponentDependencyManager.CompleteAllJobsAndInvalidateArrays () [0x00006] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\ComponentDependencyManager.cs:161
    20.   at Unity.Entities.EntityDataAccess.BeforeStructuralChange () [0x0001e] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityDataAccess.cs:424
    21.   at Unity.Entities.EntityDataAccess.BeginStructuralChanges () [0x00008] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityDataAccess.cs:430
    22.   at Unity.Entities.EntityCommandBuffer+PlaybackProcessor.Init (Unity.Entities.EntityDataAccess* entityDataAccess, Unity.Entities.EntityCommandBufferData* data, Unity.Entities.SystemHandle& originSystemHandle) [0x0003b] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityCommandBuffer.cs:3708
    23.   at Unity.Entities.EntityCommandBuffer.PlaybackInternal (Unity.Entities.EntityDataAccess* mgr) [0x0014e] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityCommandBuffer.cs:3279
    24.   at Unity.Entities.EntityCommandBuffer.Playback (Unity.Entities.EntityManager mgr) [0x00000] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityCommandBuffer.cs:3221
    25.   at Unity.Entities.EntityCommandBufferSystem.FlushPendingBuffers (System.Boolean playBack) [0x00097] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityCommandBufferSystem.cs:208
    26.  
    27. ArgumentException: Attempted to access BufferTypeHandle<IntensitySystem+SpawnData> which has been invalidated by a structural change.
    28. EntityCommandBuffer was recorded in PillarBeastSystem and played back in Unity.Entities.EndSimulationEntityCommandBufferSystem.
    29.   at (wrapper managed-to-native) Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckDeallocateAndThrow_Injected(Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle&)
    30.   at Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckDeallocateAndThrow (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) [0x00000] in <6c9b376c3fca40b787e8c1a2133bf243>:0
    31.   at Unity.Entities.ComponentSafetyHandles.CompleteAllJobsAndInvalidateArrays () [0x00018] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\ComponentSafetyHandles.cs:211
    32.   at Unity.Entities.ComponentDependencyManager.CompleteAllJobsAndInvalidateArrays () [0x00006] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\ComponentDependencyManager.cs:161
    33.   at Unity.Entities.EntityDataAccess.BeforeStructuralChange () [0x0001e] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityDataAccess.cs:424
    34.   at Unity.Entities.EntityDataAccess.BeginStructuralChanges () [0x00008] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityDataAccess.cs:430
    35.   at Unity.Entities.EntityCommandBuffer+PlaybackProcessor.Init (Unity.Entities.EntityDataAccess* entityDataAccess, Unity.Entities.EntityCommandBufferData* data, Unity.Entities.SystemHandle& originSystemHandle) [0x0003b] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityCommandBuffer.cs:3708
    36.   at Unity.Entities.EntityCommandBuffer.PlaybackInternal (Unity.Entities.EntityDataAccess* mgr) [0x0014e] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityCommandBuffer.cs:3279
    37.   at Unity.Entities.EntityCommandBuffer.Playback (Unity.Entities.EntityManager mgr) [0x00000] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityCommandBuffer.cs:3221
    38.   at Unity.Entities.EntityCommandBufferSystem.FlushPendingBuffers (System.Boolean playBack) [0x00097] in C:\Users\Monsterutan\Development\ProjectDioFresher\Packages\com.unity.entities@1.0.0-pre.15\Unity.Entities\EntityCommandBufferSystem.cs:208
    39.  

    The IComponenetData and SystemBase are unrelated, or at least so far I've not found any connection between the lines in the error message.

    I have never seen this before, and I don't know where to start because the concept of "invalidated by a structural change" inside a EntityCommandBuffer playback does not really make sense to me?

    Can anyone shed some light on this or if you've seen it?

    Thanks in advance!
     
    Last edited: Aug 27, 2023
  2. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,292
    Try on newer version of Entities. 1.0.10+ in theory should have a fix for this case.
     
    Mockarutan likes this.
  3. Mockarutan

    Mockarutan

    Joined:
    May 22, 2011
    Posts:
    158
    Could you point me to the changelog that refers to this fix?

    The reson I'm on 1.0.0-pre.15 is because every time I've tried to update beyond 0.51, I've gotten this issue:
    https://forum.unity.com/threads/pro...ntnullexception-value-cannot-be-null.1343069/

    I did spend a whole day commenting out different parts of my code and managed to get to 1.0.0-pre15, but I never figured out exactly what fixed it. And when I tried 1.0.0-pre65, I think, I got the issue again. And since then I've just not had the time or energy to go through that again. But if that's the only good solution to this issue, I will do it. I've just been putting it of for a period with more time in my planning.
     
  4. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,292
    https://docs.unity3d.com/Packages/com.unity.entities@1.0/changelog/CHANGELOG.html#fixed-2
    Also, lots of changes to how structural changes done in 1.0.10, so it might affect behaviour as well.

    I've had exactly same issue, fixing / rewriting invalid jobs did the trick for me.
    https://forum.unity.com/threads/pro...on-value-cannot-be-null.1343069/#post-9191417

    Basically, if you use Job.WithCode or EFE with ScheduleParallel (SystemBase) - rewrite them without using codegen.

    Use a dichotomy search approach - remove half of the systems, then half again, until it works, then add one-by-one to figure out what fails. Its time consuming, but can be done in a couple of days.

    And to be honest, I don't think compilation issue will be fixed.
    Because best fix would be the same exception with system name which fails. Not that much of a win.
    You'd still need to manually rewrite jobs into proper job structs anyway.
     
    Mockarutan likes this.
  5. Mockarutan

    Mockarutan

    Joined:
    May 22, 2011
    Posts:
    158
    Hmm.. Strange, I don't remember doing many changes at all when I at last got 1.0.0-pre15 compiling, still have a ton of WithCode and EFE ScheduleParallel. I just started to bring my code back one comment at a time and it worked without a lot of changes. It was more like just a few small weird anonymous errors, with no real pattern, that broke it all.

    And the no 'WithCode and EFE ScheduleParallel' is bad news... I have a deadline in a month and I really don't think I have time to rewrite all the EFEs, lot's of other things to do. The annoying thing is that I've not seen this issue before and I've been on 1.0.0-pre15 for quite a while. So something in my code has caused it. I might have to just go into my git history and find the top 10 feistiest memory operations and disable those and the features they support one by one and see if it disappears.

    Or maybe I'm missing some smarter solution?

    Thanks you for the help though! Really appreciated!
     
  6. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,292
    Its not that bad though. I've used live templates to generate IJob / IJobEntity structs, then just copied & pasted params and code to the job. Biggest issue was making sure proper queries are used.

    Alternatively, you could swap EFE.ScheduleParallel for Schedule.
    Then tear down Job.WithCode and see it that helps.
    If it helps, then the ECB issue was fixed in newer release, and its time to refactor.
    If not, you can always rollback the changes.

    Or, try clearing Library.

    I've chased a random memory leak / bug in 0.50 before, which went gone completely after Library was cleared.
    Maybe its one of those Unity things.
     
    Mockarutan likes this.
  7. Mockarutan

    Mockarutan

    Joined:
    May 22, 2011
    Posts:
    158
    I actually took the dive and upgraded, it only took about a day. I was very surprised! Thing is, EFE.ScheduleParallel or WithCode was no problem actually! There was really only one anonymous issue that caused the compilation error, a Tuple in a native collection used in a EFE.ScheduleParallel. So it was way easer than I thought, but also quite a bit of luck that I just started to comment out EFE.ScheduleParallel from you suggestion.

    So yeah, I'm on 1.0.14 now and I have not had the original issue yet, so so far so good!

    And thanks again for the help!
     
    xVergilx likes this.