Skip to content

MARSHALLED_UNICODE_STRING[] array marshalling leaks memory #76584

Description

@jkotas

The marshalling code generated for

[LibraryImport(Interop.Libraries.Advapi32,EntryPoint="LsaLookupNames2",SetLastError=true,StringMarshalling=StringMarshalling.Utf16)]
internalstaticpartialuintLsaLookupNames2(
SafeLsaPolicyHandlehandle,
intflags,
intcount,
MARSHALLED_UNICODE_STRING[]names,
outSafeLsaMemoryHandlereferencedDomains,
outSafeLsaMemoryHandlesids
);
looks like this (the code snippet only shows marshalling names argument, the remaining arguments omitted for brevity):

// <auto-generated/>unsafepartialclassTest{[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.LibraryImportGenerator","7.0.6.47809")][System.Runtime.CompilerServices.SkipLocalsInitAttribute]internalstaticpartialuintLsaLookupNames2(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=stackallocglobal::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,newSystem.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)]staticexternunsafeuint__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