Bug 27614

Summary: Native interop: out LPArrays cause crash
Product: [Mono] Runtime Reporter: Brandon Streiff <brandon.streiff>
Component: InteropAssignee: Bugzilla <bugzilla>
Status: RESOLVED FIXED    
Severity: normal CC: joe.friedrichsen, mono-bugs+mono, mono-bugs+runtime, vargaz
Priority: ---    
Version: 3.12.0   
Target Milestone: ---   
Hardware: PC   
OS: Windows   
Tags: Is this bug a regression?: ---
Last known good build:
Attachments: VS2012 project: native and managed code

Description Brandon Streiff 2015-03-03 15:47:19 UTC
Created attachment 10135 [details]
VS2012 project: native and managed code

I have a native library that returns a (native-allocated) array. Memory
is allocated using the COM allocator (CoTaskMemAlloc on Windows, malloc
on OS X/iOS), as per the rules of the interop marshaler:

   https://msdn.microsoft.com/en-us/library/f1cf4kkz(v=vs.100).aspx

The Mono documentation appears to confirm this:

   http://www.mono-project.com/docs/advanced/pinvoke/#memory-management

The attached project has two parts:
- A native DLL that exports a "getArrayData" method that builds an
  8-element array.

   extern "C" void __cdecl getArrayData(uint8_t** array, int* size);

- A managed C# application that P/Invokes the native function:

   [DllImport("ArrayMarshalNative.dll", EntryPoint="getArrayData",
      CallingConvention=CallingConvention.Cdecl,
      CharSet=CharSet.Unicode, ExactSpelling=true,
      SetLastError=false)]
   public static extern void getArrayData(
      [MarshalAs(UnmanagedType.LPArray,
                 ArraySubType=UnmanagedType.U1,
                 SizeParamIndex=1)] out byte[] data,
      out int size);

If I build and run the attached project using the MS.NET runtime/Visual
Studio 2012, then I get the expected output:

   Z:\ArrayMarshalTest\Release>ArrayMarshalTest.exe
   Calling getArrayData
   Returning from getArrayData
   Returned from getArrayData
   size == 8: True
   data != null: True
   data[0] = 3 (expecting 3)
   data[1] = 1 (expecting 1)
   data[2] = 4 (expecting 4)
   data[3] = 1 (expecting 1)
   data[4] = 5 (expecting 5)
   data[5] = 9 (expecting 9)
   data[6] = 2 (expecting 2)
   data[7] = 6 (expecting 6)

If I run it with Mono 3.12.0 (Windows), downloaded from the Mono
website:

   Z:\ArrayMarshalTest\Release>mono ArrayMarshalTest.exe
   Calling getArrayData
   Returning from getArrayData
   (process crashes)

Running with --verbose appears to give:

converting method System.Buffer:BlockCopy (System.Array,int,System.Array,int,int)
Method System.Buffer:BlockCopy (System.Array,int,System.Array,int,int) emitted at 038826D8 to 038828C0 (code length 488) [ArrayMarshalTest.exe]
converting method (wrapper managed-to-native) System.Buffer:BlockCopyInternal (System.Array,int,System.Array,int,int)
Method (wrapper managed-to-native) System.Buffer:BlockCopyInternal (System.Array,int,System.Array,int,int) emitted at 038828D8 to 03882976 (code length 158) [ArrayMarshalTest.exe]

converting method (wrapper managed-to-native) ArrayMarshalTest.Program:getArrayData (byte[]&,int&)
Method (wrapper managed-to-native) ArrayMarshalTest.Program:getArrayData (byte[]&,int&) emitted at 03882990 to 03882A99 (code length 265) [ArrayMarshalTest.exe]

converting method (wrapper managed-to-native) object:__icall_wrapper_mono_array_to_lparray (object)
Method (wrapper managed-to-native) object:__icall_wrapper_mono_array_to_lparray (object) emitted at 03882AA0 to 03882B1E (code length 126) [ArrayMarshalTest.exe]
Returning from getArrayData
converting method (wrapper managed-to-native) object:__icall_wrapper_mono_free_lparray (object,intptr)
Method (wrapper managed-to-native) object:__icall_wrapper_mono_free_lparray (object,intptr) emitted at 03882B20 to 03882B9A (code length 122) [ArrayMarshalTest.exe]


Building ArrayMarshalTest with the MS compiler or with mcs doesn't seem
to make a difference, it crashes in both cases.

If I change the LPArray marshaling to an IntPtr I do not experience a
crash.


This may be a duplicate of #24638; I was trying to build a test case to
reproduce an issue where 'out LPArray' parameters come back as null in
the Mono runtime, and ran into this crash instead.
Comment 1 Zoltan Varga 2015-03-05 14:25:36 UTC
Fixed in mono marshal f1b172fc2d26c9c447c192b38c432dd8c5d911e0.