Using UnsafeUtility.MemCpy inside a job Crashes the Editor

Hello Everyone,

im new to C# pointers and Unity’s UnsafeUtility, the Editor Crashes each time i Start the Play Mode.

// My CopyFromWriter Functions Which is crashing the Editor

 /// <summary>
    /// Copy Data From DataStreamWriter to DynamicBuffer
    /// </summary>
    /// <param name="buffer"></param>
    /// <param name="writer"></param>
    public static unsafe  void CopyFromWriter<T>(this DynamicBuffer<T> buffer, DataStreamWriter writer) where T: struct
    {
        var prevLen = buffer.Length * UnsafeUtility.AlignOf<T>();
        buffer.ResizeUninitialized(prevLen + writer.Length);
        byte* ptr = (byte*)buffer.GetUnsafePtr();
        ptr += prevLen;
        UnsafeUtility.MemCpy(ptr, writer.GetUnsafeReadOnlyPtr(), writer.Length);
    }

// My system

  [UpdateInGroup(typeof(SimulationSystemGroup))]
    public class ClientDataCollectorBeforeSendSystem : JobComponentSystem
    {
        /// <summary>
        /// Note! This Capacity should be updated if messages will be added 
        /// </summary>
        private const int outgoingWriterCapacity = 64;
        protected override void OnCreate()
        {
          
        }

        /// <summary>
        /// This Job Will Collect All Data and put them in Buffers before the Send Process
        /// </summary>
        [RequireComponentTag(
            typeof(LocalPlayerTag),
            typeof(OutgoingUnreliableMessages),
            typeof(LocalPlayerConnectedStatus))]
        [ExcludeComponent(typeof(DeadTag))]
        [BurstCompile]
        private struct FillMessageBuffers : IJobForEachWithEntity<AimInput, MovementInput>
        {
            public BufferFromEntity<OutgoingUnreliableMessages> OutgoingUnreliableMessagesFromEntity;
            public void Execute(Entity entity, int index, [ReadOnly] ref AimInput aimInput,[ReadOnly] ref MovementInput movementInput)
            {
                // Add LocalPlayer Inputs to the OutgoingStreamBuffer
                var buffer = OutgoingUnreliableMessagesFromEntity[entity];
                var writer = new DataStreamWriter(outgoingWriterCapacity, Allocator.Temp);
                writer.Write(MessageBufferIndexes.Client_JoySticksInput);
                movementInput.ToJoystickInput().Serialize(writer);
                aimInput.ToJoystickInput().Serialize(writer);
                buffer.CopyFromWriter(writer);
                writer.Dispose();
            }
        }


        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {

            var fillMessageBuffersHandle = new FillMessageBuffers
            {
                OutgoingUnreliableMessagesFromEntity = GetBufferFromEntity<OutgoingUnreliableMessages>(),

            }.ScheduleSingle(this, inputDeps);

            return fillMessageBuffersHandle;
        }
    }

========== OUTPUTTING STACK TRACE ==================

0x00007FF7D65A5867 (Unity) memcpy
0x00007FF7D4FC33BB (Unity) UnsafeUtility_CUSTOM_MemCpy
0x000001A0BE9DD7C0 (Mono JIT Code) (wrapper managed-to-native) Unity.Collections.LowLevel.Unsafe.UnsafeUtility:MemCpy (void*,void*,long)
0x000001A11F4D4833 (Mono JIT Code) [C:\UnityProjects\Century Wars _ Battle Royale\Assets\Scripts\Utils\DataUtils.cs:61] DataUtils:CopyFromWriter<CWBR.ClientAndServer.Components.OutgoingUnreliableMessages> (Unity.Entities.DynamicBuffer`1<CWBR.ClientAndServer.Components.OutgoingUnreliableMessages>,Unity.Networking.Transport.DataStreamWriter)
0x000001A11F4D0703 (Mono JIT Code) [C:\UnityProjects\Century Wars _ Battle Royale\Assets\Scripts\ECS\Systems\ClientSideOnly\Networking\ClientDataCollectorBeforeSendSystem.cs:53] CWBR.Client.Systems.ClientDataCollectorBeforeSendSystem/FillMessageBuffers:Execute (Unity.Entities.Entity,int,CWBR.ClientAndServer.Components.AimInput&,CWBR.ClientAndServer.Components.MovementInput&)
0x000001A0C1E593B3 (Mono JIT Code) [C:\UnityProjects\Century Wars _ Battle Royale\Library\PackageCache\com.unity.entities@0.1.1-preview\Unity.Entities\IJobForEach.gen.cs:2101] Unity.Entities.JobForEachExtensions/JobStruct_Process_ECC`3<CWBR.Client.Systems.ClientDataCollectorBeforeSendSystem/FillMessageBuffers, CWBR.ClientAndServer.Components.AimInput, CWBR.ClientAndServer.Components.MovementInput>:ExecuteChunk (Unity.Entities.JobForEachExtensions/JobStruct_Process_ECC`3<CWBR.Client.Systems.ClientDataCollectorBeforeSendSystem/FillMessageBuffers, CWBR.ClientAndServer.Components.AimInput, CWBR.ClientAndServer.Components.MovementInput>&,intptr,int,int,Unity.Entities.ArchetypeChunk*,int*)
0x000001A0C1E57183 (Mono JIT Code) [C:\UnityProjects\Century Wars _ Battle Royale\Library\PackageCache\com.unity.entities@0.1.1-preview\Unity.Entities\IJobForEach.gen.cs:2075] Unity.Entities.JobForEachExtensions/JobStruct_Process_ECC`3<CWBR.Client.Systems.ClientDataCollectorBeforeSendSystem/FillMessageBuffers, CWBR.ClientAndServer.Components.AimInput, CWBR.ClientAndServer.Components.MovementInput>:Execute (Unity.Entities.JobForEachExtensions/JobStruct_Process_ECC`3<CWBR.Client.Systems.ClientDataCollectorBeforeSendSystem/FillMessageBuffers, CWBR.ClientAndServer.Components.AimInput, CWBR.ClientAndServer.Components.MovementInput>&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)
0x000001A0C1E58342 (Mono JIT Code) (wrapper delegate-invoke) Unity.Entities.JobForEachExtensions/JobStruct_Process_ECC`3/ExecuteJobFunction<CWBR.Client.Systems.ClientDataCollectorBeforeSendSystem/FillMessageBuffers, CWBR.ClientAndServer.Components.AimInput, CWBR.ClientAndServer.Components.MovementInput>:invoke_void_JobForEachExtensions/JobStruct_Process_ECC`3<T, T0, T1>&_intptr_intptr_JobRanges&_int (Unity.Entities.JobForEachExtensions/JobStruct_Process_ECC`3<CWBR.Client.Systems.ClientDataCollectorBeforeSendSystem/FillMessageBuffers, CWBR.ClientAndServer.Components.AimInput, CWBR.ClientAndServer.Components.MovementInput>&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)
0x000001A0C1E2D529 (Mono JIT Code) (wrapper runtime-invoke) <Module>:runtime_invoke_void__this___intptr&_intptr_intptr_intptr&_int (object,intptr,intptr,intptr)
0x00007FFB5A09CCB0 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\mini\mini-runtime.c:2809] mono_jit_runtime_invoke
0x00007FFB5A022142 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:2921] do_runtime_invoke
0x00007FFB5A02B13F (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:2968] mono_runtime_invoke
0x00007FF7D4E0AE6E (Unity) scripting_method_invoke
0x00007FF7D4E04B4D (Unity) ScriptingInvocation::Invoke
0x00007FF7D4784255 (Unity) ExecuteJob
0x00007FF7D47852FC (Unity) ForwardJobToManaged
0x00007FF7D4773391 (Unity) JobQueue::Exec
0x00007FF7D4773AED (Unity) JobQueue::ExecuteJobFromHighPriorityStack
0x00007FF7D4775643 (Unity) JobQueue::ProcessJobs
0x00007FF7D477A9C6 (Unity) JobQueue::WorkLoop
0x00007FF7D4CC3B43 (Unity) Thread::RunThreadWrapper
0x00007FFBD39A7BD4 (KERNEL32) BaseThreadInitThunk
0x00007FFBD556CED1 (ntdll) RtlUserThreadStart

========== END OF STACKTRACE ===========

UnsafeUtility.AlignOf() seems to be hard coded to 4 right now, what you want to use is UnsafeUtility.SizeOf(). I think it will work and won’t crash the editor but you are resizing the buffer bigger than it has to be. The count for ResizeUnitialize should be element count but you are using byte count.

2 Likes

Oh thanks @temps12 !!
for an unknow reason i was using the .AlignOf() i was pretty sure i wrote .SizeOf(). XD

Yes my buffer is a buffer of Bytes im using it to stack my Networked Messages.

public struct OutgoingUnreliableMessages : IBufferElementData
    {
        public byte Value;
    }
2 Likes