Skip to content

[BUG] Race between clean and remoteFinalizer for unmanaged buffers #563

@michael-swan

Description

@michael-swan

Description
In Data.Array.Accelerate.Array.Remote.Table, there is a function called insertUnmanaged which I believe is necessary for handing off pre-existing CUDA buffers to Accelerate. There is an assumed invariant here, namely that the remoteFinalizer attached to a Weak reference is run before deRefWeak can return Nothing in clean. This is not actually always true, and deRefWeak can return Nothing before remoteFinalizer runs and thus clean will see a buffer in the table and it will be "unreferenced" and so it will invoke freeStable on it, thus you could accidentally free a buffer provided by insertUnmanaged.

Steps to reproduce
I have not seen this in the wild but this appears real from reading Data.Array.Accelerate.Array.Remote.Table. I have confirmed that this order-of-operations of deRefWeak and the finalizer logic are inconsistent in the way described above, with an example Haskell program.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions