Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice
  2. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  3. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved [Unity.Physics] Confused by SphereCollider.Create and lifetime

Discussion in 'Physics Previews' started by Baggers_, Aug 11, 2020.

  1. Baggers_

    Baggers_

    Joined:
    Sep 10, 2017
    Posts:
    98
    [EDIT]: Progress made, question revised in reply

    TLDR: I'm not sure how taking ref to local var is sound

    Hi, I was reading the Unity.Physics manual again and this line caught my eye:

    Code (CSharp):
    1. BlobAssetReference<Collider> sphereCollider = SphereCollider.Create(sphereGeometry, filter);
    I was interested, as no allocator is specified, but I knew that BlobAssetReference<T> holds a pointer to something.

    I looked at the SphereCollider.Create method and saw this (I've added the comments):

    Code (CSharp):
    1.  
    2. public static unsafe BlobAssetReference<Collider> Create(SphereGeometry geometry, CollisionFilter filter, Material material)
    3. {
    4.   var collider = default(SphereCollider); // line 1
    5.   collider.Init(geometry, filter, material); // line 2
    6.   return BlobAssetReference<Collider>.Create(&collider, sizeof(SphereCollider)); // line 3
    7. }
    Line 1 & 2 make sense to me, we make a struct (on the stack presumably), and Init sets up its local members.
    On line 3, we take a pointer to the struct, which is also fine, make the BlobAssetReference, but then we return.

    On return I assume we pop the stack, which I've assumed is storing the collider. We then would have a BlobAssetReference into the remains of that stack-frame, which is unsound.

    I've looked for parallels in c# itself, and 'ref returns' are one example. However, they explicitly forbid returning refs to local variables.

    Please can someone point me to the parts of the spec or runtime info that explain how this is valid.

    Thanks!
     
    Last edited: Aug 11, 2020
  2. Baggers_

    Baggers_

    Joined:
    Sep 10, 2017
    Posts:
    98
    AH, my bad, `BlobAssetReference<T>.Create` Allocates persistent storage and then copies the data from the src pointer into it
    Code (CSharp):
    1. public static BlobAssetReference<T> Create(void* ptr, int length)
    2. {
    3.     byte* buffer =
    4.    (byte*) UnsafeUtility.Malloc(sizeof(BlobAssetHeader) + length, 16, Allocator.Persistent);
    5.     UnsafeUtility.MemCpy(buffer + sizeof(BlobAssetHeader), ptr, length);
    6. ... ETC ...
    However this then begs another question.

    In the manual here: https://docs.unity3d.com/Packages/com.unity.physics@0.3/manual/collision_queries.html#collider-casts we see that the SphereCollider is created but never disposed. Is that a mistake?
     
  3. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Yes, this particular example is missing the dispose. You can turn on the leak detection in the editor and make sure you are disposing all the memory needed.
     
    Baggers_ likes this.
  4. Baggers_

    Baggers_

    Joined:
    Sep 10, 2017
    Posts:
    98
    petarmHavok likes this.