Bug 27614 - Native interop: out LPArrays cause crash
Summary: Native interop: out LPArrays cause crash
Status: RESOLVED FIXED
Alias: None
Product: Runtime
Classification: Mono
Component: Interop ()
Version: 3.12.0
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2015-03-03 15:47 UTC by Brandon Streiff
Modified: 2015-03-05 14:25 UTC (History)
4 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
VS2012 project: native and managed code (6.71 KB, application/x-zip-compressed)
2015-03-03 15:47 UTC, Brandon Streiff
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

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.