SIGSEGV in JobReflectionData::FinalizeReflectionData on Android device [SOLVED]

I have a generic bursted job that runs fine in the editor, but crashed on an Android device in JobReflectionData::FinalizeReflectionData. It turned out I was missing RegisterGenericJobType for all the types used with the job. It would be nice if Unity could print a warning for this, like it’s doing for missing RegisterGenericComponentType. Since I didn’t get any Google results for this crash, I wanted to give a solution to how it can be fixed. Maybe it spares someone a headache. :slight_smile:

Hi @polynatic

First off, thanks for writing out what happened to you and your solution in the hopes of possibly helping someone else in the future :slight_smile: and for sharing your suggestion!

We just discussed your post internally and became curious about what the crash you experienced looked like in particular. Seeing the crash data could inform us about how we specifically could (if we could) produce warnings like you suggest in this particular situation. If possible, could you share your crash data with us here, so we can investigate further?

Again, thanks for your message polynatic!

Hi @Miro_Brodlova,

Thank you! Sure, here is the crash log I got. If you need any more information, I can recreate it. The project setup is Unity 2022.3.40f1, Entities v1.3.2 and Burst v1.8.17. The code simplified looks like this:

using Unity.Burst;
using Unity.Burst.Intrinsics;
using Unity.Entities;
using Unity.Jobs;

[assembly: RegisterGenericJobType(typeof(ProcessGeneric.GenericJob<ImplementsInterface>))]

public interface IInterface
{
    float SomeProperty { get; set; }
}

public struct ImplementsInterface : IComponentData, IInterface
{
    public float Value;

    public float SomeProperty
    {
        get => Value;
        set => Value = value;
    }
}

internal partial struct ProcessGeneric : ISystem
{
    private EntityQuery Query;

    [BurstCompile]
    public void OnCreate(ref SystemState state)
    {
        // ... create Query and ComponentTypeHandles
    }
    
    [BurstCompile]
    public void OnUpdate(ref SystemState state)
    {
        state.Dependency = new GenericJob<ImplementsInterface>().Schedule(Query, state.Dependency);
    }

    [BurstCompile]
    internal struct GenericJob<TValue> : IJobChunk
        where TValue : unmanaged, IComponentData, IInterface
    {
        [BurstCompile]
        public void Execute(
            in ArchetypeChunk chunk,
            int unfilteredChunkIndex,
            bool useEnabledMask,
            in v128 chunkEnabledMask)
        {
            // ...
        }
    }
}

When the RegisterGenericJobType is removed, the build will crash on the device. The device is a Meta Quest 2 if that is of any help.

Thank you so much for the details and log @polynatic, this is very helpful!

Taking it all with me to the team right away, will get back to you when I/we have more :slight_smile:

I’m back!

From the details provided @tim_jones from the team suggested that a stripping problem may be causing the crash, which would be interesting. (possibly the GenericJob<TValue>.Execute method is incorrectly being stripped from the managed assembly).

To confirm this for us, could you possibly test the following on your setup (that reproduces the crash):

Steps to check if it’s a stripping crash:

  1. In the code that reproduces the crash, remove the [assembly: RegisterGenericJobType(typeof(ProcessGeneric.GenericJob<ImplementsInterface>))] line.
  2. Add [Preserve] on the GenericJob<TValue> type.
  3. Run your setup and note if it’s still crashing.

Would it be possible for you to follow steps above and get back to us with the outcome? This would help us narrow things down even further.

Again, thanks so much @polynatic for not only writing here to help others, but also for providing us with so many great details :slight_smile: