Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Returning Span<T> assumes memory management #79413

Open
AaronRobinsonMSFT opened this issue Dec 8, 2022 · 2 comments
Open

Returning Span<T> assumes memory management #79413

AaronRobinsonMSFT opened this issue Dec 8, 2022 · 2 comments

Comments

@AaronRobinsonMSFT
Copy link
Member

AaronRobinsonMSFT commented Dec 8, 2022

The XGBoost API contains several APIs where memory management is internally handled and callers are assumed to ignore the lifetime concern. For example, consider the possible projection of the XGDMatrixGetFloatInfo API.

public static partial int XGDMatrixGetFloatInfo(
    IntPtr handle,
    string field,
    out ulong len,
    [MarshalUsing(CountElementName = "len")] out Span<float> result);

The above API suffers from two deficiencies. The first is the returned length is a ulong (64-bit), but Span<T> only supports lengths of int, the other is the returned pointer will be copied into managed memory by source generated and the unmanaged pointer freed by the Span<T> marshaller. The semantics of the C API dictate the unmanaged memory shouldn't be freed, so when it is heap corruption will ensue.

We should consider a mechanism for indicating returned unmanaged memory isn't to be freed. Note this particular API would still be broken due to the int vs ulong length conflict.

Related: #76974

@ghost
Copy link

ghost commented Dec 8, 2022

Tagging subscribers to this area: @dotnet/interop-contrib
See info in area-owners.md if you want to be subscribed.

Issue Details

The XGBoost API contains several APIs where memory management is internally handled and callers are assumed to ignore the lifetime concern. For example, consider the possible projection of the XGDMatrixGetFloatInfo API.

public static partial int XGDMatrixGetFloatInfo(
    IntPtr handle,
    string field,
    out ulong len,
    [MarshalUsing(CountElementName = "len")] out Span<float> result);

The above API suffers from two deficiencies. The first is the returned length is a ulong (64-bit), but Span<T> only supports lengths of int, the other is the returned pointer will be copied into managed memory by source generated and the unmanaged pointer freed by the Span<T> marshaller. The semantics of the C API dictate the unmanaged memory shouldn't be freed so when it is heap corruption will ensue.

We should consider a mechanism for indicating returned unmanaged memory isn't to be freed. Note this particular API would still be broken due to the int vs ulong length conflict.

Related: #76974

Author: AaronRobinsonMSFT
Assignees: -
Labels:

area-System.Runtime.InteropServices

Milestone: Future

@elinor-fung
Copy link
Member

Same deal for array:

public static partial int XGDMatrixGetFloatInfo(
    IntPtr handle,
    string field,
    out ulong len,
    [MarshalUsing(CountElementName = "len")] out float[] result);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Development

No branches or pull requests

2 participants