Skip to content

MARSHALLED_UNICODE_STRING[] array marshalling leaks memory #76584

Closed
@jkotas

Description

@jkotas

The marshalling code generated for

[LibraryImport(Interop.Libraries.Advapi32, EntryPoint = "LsaLookupNames2", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
internal static partial uint LsaLookupNames2(
SafeLsaPolicyHandle handle,
int flags,
int count,
MARSHALLED_UNICODE_STRING[] names,
out SafeLsaMemoryHandle referencedDomains,
out SafeLsaMemoryHandle sids
);
looks like this (the code snippet only shows marshalling names argument, the remaining arguments omitted for brevity):

// <auto-generated/>
unsafe partial class Test
{
    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.LibraryImportGenerator", "7.0.6.47809")]
    [System.Runtime.CompilerServices.SkipLocalsInitAttribute]
    internal static partial uint LsaLookupNames2(global::Test.MARSHALLED_UNICODE_STRING[] names)
    {
        int __lastError;
        global::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native* __names_native = default;
        uint __retVal;
        // Setup - Perform required setup.
        global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<global::Test.MARSHALLED_UNICODE_STRING, global::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native>.ManagedToUnmanagedIn __names_native__marshaller = new();
        try
        {
            // Marshal - Convert managed data to native data.
            global::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native* __names_native__stackptr = stackalloc global::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native[global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<global::Test.MARSHALLED_UNICODE_STRING, global::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native>.ManagedToUnmanagedIn.BufferSize];
            __names_native__marshaller.FromManaged(names, new System.Span<global::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native>(__names_native__stackptr, global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<global::Test.MARSHALLED_UNICODE_STRING, global::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native>.ManagedToUnmanagedIn.BufferSize));
            {
                System.ReadOnlySpan<global::Test.MARSHALLED_UNICODE_STRING> __names_native__managedSpan = __names_native__marshaller.GetManagedValuesSource();
                System.Span<global::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native> __names_native__nativeSpan = __names_native__marshaller.GetUnmanagedValuesDestination();
                for (int __i0 = 0; __i0 < __names_native__managedSpan.Length; ++__i0)
                {
                    __names_native__nativeSpan[__i0] = global::Test.MARSHALLED_UNICODE_STRING.Marshaller.ConvertToUnmanaged(__names_native__managedSpan[__i0]);
                }
            }

            // Pin - Pin data in preparation for calling the P/Invoke.
            fixed (void* __names_native__unused = __names_native__marshaller)
            {
                // PinnedMarshal - Convert managed data to native data that requires the managed data to be pinned.
                __names_native = __names_native__marshaller.ToUnmanaged();
                System.Runtime.InteropServices.Marshal.SetLastSystemError(0);
                __retVal = __PInvoke(__names_native);
                __lastError = System.Runtime.InteropServices.Marshal.GetLastSystemError();
            }
        }
        finally
        {
            // Cleanup - Perform required cleanup.
            __names_native__marshaller.Free();
        }

        System.Runtime.InteropServices.Marshal.SetLastPInvokeError(__lastError);
        return __retVal;
        // Local P/Invoke
        [System.Runtime.InteropServices.DllImportAttribute("Advapi32", EntryPoint = "LsaLookupNames2", ExactSpelling = true)]
        static extern unsafe uint __PInvoke(global::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native* names);
    }
}

Notice that there is no cleanup of the unmanaged array after the PInvoke. Are the unmanaged string copies leaking?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions