Search Unity

Question Memory access violation EntityCommandBuffer

Discussion in 'Entity Component System' started by lukasleder, Jan 18, 2022.

  1. lukasleder

    lukasleder

    Joined:
    Sep 7, 2017
    Posts:
    16
    We're experiencing some seemingly random crashes at the moment and I was wondering if somebody has any idea what it could be.

    I've attached the error log and here is the corresponding burst compile method that is mentioned in the stacktrace:

    Code (CSharp):
    1. --method=Unity.Entities.EntityCommandBuffer, Unity.Entities, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null::_mono_to_burst_PlaybackChainChunk(System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|Unity.Entities.EntityComponentStore+ArchetypeChanges&, Unity.Entities, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|Unity.Entities.ECBSharedPlaybackState&, Unity.Entities, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|Unity.Entities.PlaybackPolicy, Unity.Entities, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)--34146f210f5f72cb3338fe0fb7212d4f
    Any potential ideas or ways we could further narrow this down are greatly appreciated.
     

    Attached Files:

  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    This is nearly always caused by unsafe ECB operations. For example

    ECB1.DestroyEntity(entity)
    ECB2.[Add|Remove|Set]Component(entity)

    ECB1 plays back, destroy entity
    ECB2 plays back, entity doesn't exist, crashes

    For safety I would suggest doing what I've dubbed, the Eizenhorn's approach - create a second EntityCommandBufferSystem dedicated to Destroy operations which runs after your EndSimulationEntityCommandBufferSystem and limit all destroy calls to this new command buffer. This way destroy should always be safe.

    The one other fail that can happen is

    ECB1.RemoveComponent(entity, ComponentA)
    ECB2.SetComponent(entity, ComponentA)

    ComponentA no longer exists so this is not safe. The fix is either structure your code in a way this can't happen or avoid using SetComponent and instead just always use AddComponent.
     
    eizenhorn likes this.
  3. lukasleder

    lukasleder

    Joined:
    Sep 7, 2017
    Posts:
    16
    Thanks a lot for the answer, I'll look into it, this is definitely a starting point!