Search Unity

Bug Caution: Job Scheduling Bug introduced in 2022.2.20

Discussion in 'Entity Component System' started by FaithlessOne, Jun 2, 2023.

  1. FaithlessOne

    FaithlessOne

    Joined:
    Jun 19, 2017
    Posts:
    320
    In Unity 2022.2.20 a severe bug in the C# Job Scheduling System occurs causing a
    SIGSEGV (Segmentation fault). As a result Unity Editor crashes while being in play mode. The bug happens sporadically, but most of the time Unity Editor crashes within the first 5 minutes being in play mode in my project. I don't know whether the bug is ECS related or also happening when using the C# Job System standalone, but due to relying heavily on jobs it will probably more likely appear in ECS projects. The bug is also included in 2022.3.0 LTS but does NOT occur in 2022.2.19.

    In case of someone from Unity is reading and interested, this is the crash log:
    Unfortunately I cannot report a crash bug, because it would require uploading my project.
     
    lavos2300 likes this.
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    Show your ProcessShotsJob fields and where you initialise (and schedule) them.
     
  3. n3b

    n3b

    Joined:
    Nov 16, 2014
    Posts:
    56
    I consistently see the same issue appearing in 2023.2.
     
  4. FaithlessOne

    FaithlessOne

    Joined:
    Jun 19, 2017
    Posts:
    320
    The bug does not always happen on the same job, like ProcessShotsJob, but also on other jobs of my project. Especially on the ProcessShotsJob and the corresponding system the last relevant change I made was a couple of weeks ago and it worked flawlessly back then. That was the reason I tried some prior versions of Unity and found out that the bug was not there then.

    But still here is the relevant code of the system and the job:
    Code (CSharp):
    1.  
    2.   [BurstCompile]
    3.   [DisableAutoCreation]
    4.   [WorldSystemFilter(WorldSystemFilterFlags.ServerSimulation | WorldSystemFilterFlags.ClientSimulation)]
    5.   [UpdateInGroup(typeof(GamePredictedFixedSystemGroup))] // custom system group (only used for grouping my systems)
    6.   [UpdateAfter(typeof(MotionSystem))]
    7.   public partial struct ShootingProcessorSystem : ISystem
    8.   {
    9.     private BeginLevelSimulationCommandBufferSystem.Singleton _beginLevelSimulationCommandBufferSystemSingleton;
    10.  
    11.     private bool _isServer;
    12.     private LoggerHandle _logger;
    13.  
    14.     private ProcessShotsJob _processShotsJob;
    15.     private EntityQuery _processShotsQuery;
    16.     private FixedString32Bytes _worldName;
    17.  
    18.     /// <inheritdoc />
    19.     public void OnCreate(ref SystemState state)
    20.     {
    21.       state.DetermineShortWorldName(out this._worldName);
    22.       this._logger = LogFactory.CreateLogger(nameof(ShootingProcessorSystem));
    23.       Log.To(this._logger).Info("[{SystemTime}/{WorldName}] Creating system", SystemAPI.Time.ElapsedTime, this._worldName);
    24.  
    25.       // System data
    26.       this._isServer = state.WorldUnmanaged.IsServer();
    27.  
    28.       // Jobs
    29.       this._processShotsJob = new ProcessShotsJob()
    30.       {
    31.         // Various
    32.         JobLogger = LogFactory.CreateLogger(nameof(ShootingProcessorSystem), nameof(ProcessShotsJob)),
    33.         WorldName = this._worldName,
    34.  
    35.         // Buffers and arrays
    36.         RaycastHits = new NativeList<RaycastHit>(20, Allocator.Persistent),
    37.       };
    38.       this._processShotsJob.Init(ref state);
    39.  
    40.       // Queries
    41.       this._processShotsQuery = SystemAPI.QueryBuilder()
    42.         .WithAspect<ShootingAspect>()
    43.         .Build();
    44.  
    45.       // Get singleton of custom command buffer system
    46.       // (Buffer is implemented as described here: https://docs.unity3d.com/Packages/com.unity.entities@1.0/manual/systems-entity-command-buffer-automatic-playback.html)
    47.       this._beginLevelSimulationCommandBufferSystemSingleton = SystemAPI.GetSingleton<BeginLevelSimulationCommandBufferSystem.Singleton>();
    48.  
    49.       // Requires
    50.       state.RequireForUpdate<PhysicsWorldSingleton>();
    51.       state.RequireForUpdate<PhysicsWorldHistorySingleton>();
    52.       state.RequireForUpdate<NetworkTime>();
    53.       state.RequireForUpdate(this._processShotsQuery);
    54.     }
    55.  
    56.     /// <inheritdoc />
    57.     [BurstCompile]
    58.     public void OnDestroy(ref SystemState state)
    59.     {
    60.       this._processShotsJob.RaycastHits.Dispose();
    61.     }
    62.  
    63.     /// <inheritdoc />
    64.     [BurstCompile]
    65.     public void OnUpdate(ref SystemState state)
    66.     {
    67.       if (!NetcodeUtilities.TryGetNetworkTime(SystemAPI.GetSingleton<NetworkTime>(), out var networkTime))
    68.       {
    69.         return;
    70.       }
    71.  
    72.       this._processShotsJob.CommandBuffer = this._beginLevelSimulationCommandBufferSystemSingleton.CreateCommandBuffer(state.WorldUnmanaged);
    73.       this._processShotsJob.NetworkTime = networkTime;
    74.       this._processShotsJob.PhysicsWorldSingleton = SystemAPI.GetSingleton<PhysicsWorldSingleton>();
    75.       this._processShotsJob.PhysicsWorldHistorySingleton = SystemAPI.GetSingleton<PhysicsWorldHistorySingleton>();
    76.  
    77.       ref var job = ref this._processShotsJob;
    78.       job.Update(ref state);
    79.       state.Dependency = job.ScheduleByRef(this._processShotsQuery, state.Dependency);
    80.     }  
    81.  
    82.     [BurstCompile]
    83.     private partial struct ProcessShotsJob : IJobEntity
    84.     {
    85.       public EntityCommandBuffer CommandBuffer;
    86.  
    87.       [ReadOnly]
    88.       public ComponentLookup<CommandDataInterpolationDelay> CommandDataInterpolationDelayLookup;
    89.  
    90.       [ReadOnly]
    91.       public bool IsServer;
    92.  
    93.       [ReadOnly]
    94.       public LoggerHandle JobLogger;
    95.  
    96.       [ReadOnly]
    97.       public ComponentLookup<LinkedConnection> LinkedConnectionLookup;
    98.  
    99.       [ReadOnly]
    100.       public ComponentLookup<LinkedInputNode> LinkedInputNodeLookup;
    101.  
    102.       [ReadOnly]
    103.       public ComponentLookup<NetworkId> NetworkIdLookup;
    104.  
    105.       [ReadOnly]
    106.       public NetworkTime NetworkTime;
    107.  
    108.       [ReadOnly]
    109.       public PhysicsWorldHistorySingleton PhysicsWorldHistorySingleton;
    110.  
    111.       [ReadOnly]
    112.       public PhysicsWorldSingleton PhysicsWorldSingleton;
    113.  
    114.       [ReadOnly]
    115.       public BufferLookup<PlayerInputElement> PlayerInputElementLookup;
    116.  
    117.       [ReadOnly]
    118.       public BufferLookup<UnitAnimationHistoryStateElement> UnitAnimationHistoryStateElementLookup;
    119.  
    120.       [ReadOnly]
    121.       public Entity PureImmediateShotPrefabEntity;
    122.  
    123.       public NativeComparers.RaycastHitDistanceComparer RaycastHitDistanceComparer;
    124.       public NativeList<RaycastHit> RaycastHits;
    125.  
    126.       [ReadOnly]
    127.       public WeaponDefinitionPoolReference WeaponDefinitionPoolReference;
    128.  
    129.       [ReadOnly]
    130.       public FixedString32Bytes WorldName;
    131.  
    132.       public void Init(ref SystemState state)
    133.       {
    134.         var prefabContainer = state.GetEntityQuery(ComponentType.ReadOnly<PurePrefabContainer>()).GetSingleton<PurePrefabContainer>();
    135.         this.PureImmediateShotPrefabEntity = prefabContainer.PureImmediateShotPrefab;
    136.  
    137.         this.IsServer = state.WorldUnmanaged.IsServer();
    138.  
    139.         this.LinkedConnectionLookup = state.GetComponentLookup<LinkedConnection>(true);
    140.         this.NetworkIdLookup = state.GetComponentLookup<NetworkId>(true);
    141.         this.CommandDataInterpolationDelayLookup = state.GetComponentLookup<CommandDataInterpolationDelay>(true);
    142.         this.LinkedInputNodeLookup = state.GetComponentLookup<LinkedInputNode>(true);
    143.         this.PlayerInputElementLookup = state.GetBufferLookup<PlayerInputElement>(true);
    144.         this.UnitAnimationHistoryStateElementLookup = state.GetBufferLookup<UnitAnimationHistoryStateElement>(true);
    145.  
    146.         this.WeaponDefinitionPoolReference = state.GetEntityQuery(ComponentType.ReadOnly<WeaponDefinitionPoolReference>()).GetSingleton<WeaponDefinitionPoolReference>();
    147.       }
    148.  
    149.       [BurstCompile]
    150.       public void Update(ref SystemState state)
    151.       {
    152.         this.LinkedConnectionLookup.Update(ref state);
    153.         this.NetworkIdLookup.Update(ref state);
    154.         this.CommandDataInterpolationDelayLookup.Update(ref state);
    155.         this.LinkedInputNodeLookup.Update(ref state);
    156.         this.PlayerInputElementLookup.Update(ref state);
    157.         this.UnitAnimationHistoryStateElementLookup.Update(ref state);
    158.       }
    159.  
    160.       [BurstCompile]
    161.       public void Execute(ShootingAspect shootingAspect)
    162.       {
    163.         // ...
    164.       }
    165.     }
    166.  
    167.     private readonly partial struct ShootingAspect : IAspect
    168.     {
    169.       public readonly RefRO<LinkedFaction> LinkedFactionRef;
    170.  
    171.       [Optional]
    172.       public readonly RefRO<LinkedPlayer> LinkedPlayerRef;
    173.  
    174.       public readonly RefRO<LocalTransform> LocalTransformRef;
    175.       public readonly RefRO<PureUnit> PureUnitRef;
    176.  
    177.       public readonly RefRW<UnitAttacking> UnitAttackingRef;
    178.       public readonly Entity UnitEntity;
    179.       public readonly RefRO<UnitMotion> UnitMotionRef;
    180.       public readonly RefRW<UnitWieldedWeapon> UnitWieldedWeaponRef;
    181.     }
    182.   }
    183.  
    184.   [BurstCompile]
    185.   public static class NativeComparers
    186.   {
    187.     [BurstCompile]
    188.     public struct RaycastHitDistanceComparer : IComparer<RaycastHit>
    189.     {
    190.       public float3 Origin;
    191.  
    192.       [BurstCompile]
    193.       public int Compare(RaycastHit a, RaycastHit b)
    194.       {
    195.         var aDistance = math.distance(this.Origin, a.Position);
    196.         var bDistance = math.distance(this.Origin, b.Position);
    197.  
    198.         if (aDistance < bDistance)
    199.         {
    200.           return -1;
    201.         }
    202.         else if (aDistance > bDistance)
    203.         {
    204.           return 1;
    205.         }
    206.         else
    207.         {
    208.           return 0;
    209.         }
    210.       }
    211.     }
    212.   }
    213.  
    Interessting, thanks for sharing this info. So it is not a specific project releated issue in your or my project.
     
    Last edited: Jun 3, 2023
  5. n3b

    n3b

    Joined:
    Nov 16, 2014
    Posts:
    56
    In my case it's the same job each time
     
  6. UniqueCode

    UniqueCode

    Joined:
    Oct 20, 2015
    Posts:
    65
    You can actually submit a bugreport (crashdump). In the crash reporter, on the bottom, click the project and then remove. This will upload the crashdump only which is usually enough for crashes in native code.
     
  7. desertGhost_

    desertGhost_

    Joined:
    Apr 12, 2018
    Posts:
    260
    Maybe one of your systems is running into an unguarded safety violation?

     
  8. FaithlessOne

    FaithlessOne

    Joined:
    Jun 19, 2017
    Posts:
    320
    I have two different jobs causing the crash. One is an IJobEntity (stated in my post above) and one is an IJob. Interesstingly the error occurs for an IJobParallelFor in your case. In my case most of the time the crash is caused by scheduling the IJob so it seems to be more likely happening when using jobs which are NOT tied to IComponentData and the ECS workflow.

    Thanks for sharing the info. In the stated case I use an aspect as Execute parameter which is also included in the entity query, so all should be fine here. I do not use InternalCompilerInterface anywhere in my project.

    Thanks for the info. I was not aware of this. I created and sent the crash report to Unity including the dumps but excluding the project itself. If I got news on this I will post here.
     
  9. n3b

    n3b

    Joined:
    Nov 16, 2014
    Posts:
    56
    Updated to 2023.2.18 and now it is much worse than before. It now takes less than a minute for editor to crash (total seconds in play mode summarized).
    Downgraded back to 2023.2.17 and can run for minutes without a crash.
    So it does look like a leak/regression in the core.
     
  10. FaithlessOne

    FaithlessOne

    Joined:
    Jun 19, 2017
    Posts:
    320
    lavos2300 and n3b like this.
  11. SchnozzleCat

    SchnozzleCat

    Joined:
    Oct 23, 2013
    Posts:
    42
    Happening to me as well after upgrading from 2022.2.18 to 2022.3.1 and from 1.0.0pre65 to 1.0.10.

    Commenting out the specific job only causes a different job to crash on the
    JobsUtility:Schedule_Injected
    function, and it consistently happens after roughly 20 seconds of running in playmode.
     
  12. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,269
    It is very inconsistent but I am also seeing this. It is a schedule-time crash, meaning it is crashing on the main thread and has nothing to do with the user Execute method inside the job.
     
  13. desertGhost_

    desertGhost_

    Joined:
    Apr 12, 2018
    Posts:
    260
    Seeing this very rarely in 2022.3.0f1 (after long periods in play mode), but seeing it every time ~20 seconds after entering play mode in 2022.3.1f1.
     
  14. HomeLabourer

    HomeLabourer

    Joined:
    Jul 11, 2022
    Posts:
    3
    [BurstCompile]OnUpdate(ref SystemState state){

    var job1 = new Job1();
    state.Dependency = job1.Schedual(state.Dependency);

    var job2 = new Job2();
    state.Dependency = job2.SchedualParallel(state.Dependency);
    }

    Crash on JobsUtility:Schedule_Injected.

    Removing [BurstCompile] solved this problem.
     
  15. FaithlessOne

    FaithlessOne

    Joined:
    Jun 19, 2017
    Posts:
    320
    I have stayed with Version 2022.2.19, but because I hade some other issues I tried whether or not they also appear in 2022.3.4. But I noticed the crash caused by the scheduling bug does no more occur in my project (without and with Burst compilation). Played three times ten minutes in a row without Editor crash. But the corresponding issue is still pending. The [BurstCompile] atttribute is still their in the system and job, which originally caused the crash since 2022.2.20 in my project. Can someone approve or disapprove that the crash bug has been fixed in his project in Unity 2022.3.4?