Search Issue Tracker

Fixed in 2022.2.X

Fixed in 2020.3.X, 2021.2.X, 2022.1.X

Votes

3

Found in

2019.4

2019.4.9f1

2021.1

Issue ID

1294627

Regression

No

NativeArray<byte>.GetSubArray() with an odd index number is empty when passed to IJob as argument

Scripting

-

How to reproduce:
1. Open attached project "1294627.zip"
2. Enter Play mode

Expected result: When passed to IJob, NativeArray<byte> subArray works both when the starting index number is odd or even
Actual result: NativeArray<byte> subArray only works with even starting index number, subArrays with odd starting index number throw errors because they are empty

Reproducible with: 2019.4.16f1, 2020.1.16f1, 2020.2.0b14, 2021.1.0a8
Couldn't test with: 2018.4 (Failed to downgrade to a functioning project)

Note: NativeArray with any other type expect from System.Byte and System.SByte works as expected

  1. Resolution Note (fix version 2022.2):

    Fixed in: 2022.2.0a1

  2. Resolution Note (fix version 2022.1):

    Fixed in 2022.1.0b3

  3. Resolution Note (fix version 2021.2):

    Fixed in: 2021.2.8f1

  4. Resolution Note (fix version 2020.3):

    Fixed in: 2020.3.26f1

Comments (2)

  1. LennartJohansen

    Jan 16, 2022 15:41

    Looks like this fix broke using NativeList.AsDeferredJobArray() as parameters in IJobParallelForDefer jobs.

    From Unity 2021.8f1 this results in errors accessing the array data in the jobs.

  2. KnuckleCracker

    Nov 04, 2021 19:13

    The following script reproduces the issue along with additional notes:
    --
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using Unity.Collections;
    using Unity.Jobs;
    using Unity.Collections.LowLevel.Unsafe;

    //Problem:
    //A NativeArray<byte>.GetSubArray(odd_start, some_length) passed to a job will appear as not created and with a length of 0 inside the job.
    //This only happens for a NativeArray of bytes. A NativeArray<short> and NativeArray<int> does not appear to show the problem.
    //Additionally, the NativeArray<byte> must be created with ClearedMemory. UnitializedMemory does not reproduce the problem.
    //Additionally the 'start' arguement to GetSubArray must be odd. An even value does not appear to reproduce the problem.

    public class TestScript : MonoBehaviour {

    private NativeArray<byte> byteArray;

    private unsafe void Awake() {
    //The problem does not occur if NativeArrayOptions.UnitializedMemory is set. Only if the byteArray clears memory (the default) does the problem occur.
    byteArray = new NativeArray<byte>(1024, Allocator.Persistent);

    //The following also reproduces the problem. The Unitialized memory part is OK, but the MemClear afterwards causes the problem the recur.
    //Note the length of memory to clear must be even.
    //byteArray = new NativeArray<byte>(1024, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
    //UnsafeUtility.MemClear(byteArray.GetUnsafePtr<byte>(), 2); //Here, the length to clear must be even to reproduce the problem.
    }

    private void Update() {
    TestJob job = new TestJob {
    //If GetSubArray start is even, things are OK.
    //If GetSubArray start is odd, the bytearray inside the job appears to be disposed or uninitialized.
    data = byteArray.GetSubArray(1, 512) //length doesn't seem to matter. Start must be odd to reproduce the problem.
    };
    Debug.Log("A: job.data IsCreated=" + job.data.IsCreated); //job.data is OK as expected
    job.Run(); // Inside run, the byteArray will appear as NOT created. This problem only happens if the first arg to GetSubArray above is odd and only if byteArray was created with cleared memory.
    Debug.Log("B: job.data IsCreated=" + job.data.IsCreated); //job.data is still OK, which is interesting given it wasn't OK inside the job's Execute method.
    //job.Schedule().Complete(); //Run vs Schedule makes no difference.
    }

    //BurstCompile doesn't seem to matter for problem reproduction
    private struct TestJob : IJob {
    [ReadOnly] public NativeArray<byte> data;

    public void Execute() {
    //if the byteArray were NativeArray<int> or NativeArray<short> everything would be OK.
    Debug.Log("INSIDE: job.data IsCreated=" + data.IsCreated);
    }
    }

    private void OnDisable() {
    if (byteArray.IsCreated) byteArray.Dispose();
    }
    }

Add comment

Log in to post comment

All about bugs

View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.