title: FatalExecutionEngineError during C# Marshalling
body: <p>I'm running into an issue when trying to read c++ structures from memofields in a number of DBase IV files into C# (.Net 4) and then insert them into MSSQL 2008.  The data is being extracted ok from the DBase files but I seemed to be doing something wrong with managing the unsafe calls because I randomly get the following error:</p>
  
  <pre><code>FatalExecutionEngineError was detected
  Message: The runtime has encountered a fatal error. The address of the error was
  at 0x791fa62c, on thread 0x16c0. The error code is 0xc0000005. This error may be
  a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common
  sources of this bug include user marshaling errors for COM-interop or PInvoke, 
  which may corrupt the stack. 
  </code></pre>
  
  <p>The following is the code I use to read the data.  This code completes successfully and the data I get from the files are correct.  The error occurs a number of minutes after this function is called, when the objects are being inserted into the database using nhibernate (I left it out because I didn't think it really matter to the issue).        </p>
  
  <pre><code>[StructLayout(LayoutKind.Sequential, Pack = 1)]
  public struct Event
  {        
      public int      Number;
      public int      Month;
      public int      Day;
      public int      Year;
      public int      Hour;
      public int      Minute;
      public int      Second;
      public UInt32   UPCTime;
      public int      BlobSize;
      [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = DataLengths.MAX_EVENT_TITLE_LENGTH)]
      public string   Title;
      [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = DataLengths.MAX_TRIGGER_LENGTH)]
      public string Trigger;
   }
  
  public struct Trigger
  {
      [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 1)]
      public string Control;
      public int Index;
      [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 1)]
      public string Mode;
      [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 1)]
      public string RecordFreq;
      public int Pre;
      public int Post;
      [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 1)]
      public string Source;
      public int Delay;
      public int EventUserNotify;
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
      public int[] Spare;
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = DataLengths.MAX_EVENT_SENSORS)]
      public int[] Sensors;
  }
  
  [StructLayout(LayoutKind.Sequential, Pack = 1)]
  public struct Value
  {
      public Trigger Trigger;
      public string[] SensorLabels;
      public Point[] Point;
  }
  
  [StructLayout(LayoutKind.Sequential, Pack = 1)]
  public struct Point
  {
      public Single Value;
      [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 1)]
      public string State;
  }
  
  //The dbf is from the java xBasej library that I compiled into a dll using IKVM.net
  public Dictionary&lt;Event, Value&gt; Read(DBF dbf)
  {     
  Dictionary&lt;Event, Value&gt; eventData = new Dictionary&lt;Event, Value&gt;();
  
  try
  {
      for (int i = 1; i &lt;= dbf.getRecordCount(); i++)
      {
           dbf.gotoRecord(i);
           MemoField memofield = (MemoField)dbf.getField("MemoField");
  
           // Perform the conversion from one encoding to the other.
           byte[] blob = memofield.getBytes();
  
           if (blob.Length == 0)
           {
               continue;
           }
  
           MemoryStream memoryStream = null;
           BinaryReader binaryReader = null;
           GCHandle eventHandle = new GCHandle();
           GCHandle triggerHandle = new GCHandle();
           GCHandle sensorLabelHandle = new GCHandle();
           GCHandle pointHandle = new GCHandle();
  
           try
           {
               memoryStream = new MemoryStream(blob);
               binaryReader = new BinaryReader(memoryStream);
  
               //The data was orignally C++ structures so we read the bytes back into C# equivalent
               //structures.
               int eventDataSize = Marshal.SizeOf(typeof(Event));
  
               eventHandle = GCHandle.Alloc(binaryReader.ReadBytes(eventDataSize), GCHandleType.Pinned);
               Event @event = (Event)Marshal.PtrToStructure(eventHandle.AddrOfPinnedObject(), typeof(Event));
  
               //Read the event trigger data
               int triggerDataSize = Marshal.SizeOf(typeof(Trigger));
               triggerHandle = GCHandle.Alloc(binaryReader.ReadBytes(triggerDataSize), GCHandleType.Pinned);
               Trigger trigger = (Trigger)Marshal.PtrToStructure(triggerHandle.AddrOfPinnedObject(), typeof(Trigger));
  
               Value value = new Value();
               value.Trigger = trigger;
  
               triggerHandle.Free();
  
               //Read all the sensor labels
               List&lt;string&gt; sensorLableList = new List&lt;string&gt;();
               for (int sensorIndex = 0; sensorIndex &lt; DataLengths.MAX_EVENT_SENSORS; sensorIndex++)
               {
                     int sensorLableDataSize = DataLengths.MAX_LABEL_LENGTH;
                     sensorLabelHandle = GCHandle.Alloc(binaryReader.ReadBytes(sensorLableDataSize), GCHandleType.Pinned);
                    string label = Marshal.PtrToStringAnsi(sensorLabelHandle.AddrOfPinnedObject(), sensorLableDataSize).Trim();
                     sensorLableList.Add(label);
  
                     sensorLabelHandle.Free();
               }
               value.SensorLabels = sensorLableList.ToArray();
               //Read all the recorded sensor data
               List&lt;Point&gt; pointList = new List&lt;Point&gt;();
               for (int pointIndex = 0; pointIndex &lt; DataLengths.MAX_EVENT_SENSORS; pointIndex++)
               {
                    int pointDataSize = Marshal.SizeOf(typeof(Point));
  
                    pointHandle = GCHandle.Alloc(binaryReader.ReadBytes(pointDataSize), GCHandleType.Pinned);
                    Point point = (Point)Marshal.PtrToStructure(pointHandle.AddrOfPinnedObject(), typeof(Point));
                    pointList.Add(point);
  
                    pointHandle.Free();
               }
  
               value.Point = pointList.ToArray();
  
               eventData.Add(@event, value);
               eventHandle.Free();
          }
          finally
          {
               //Free all the resources used to get the data
               if (memoryStream != null) { memoryStream.Close(); }
               if (binaryReader != null) { binaryReader.Close(); }
               if (eventHandle.IsAllocated) { eventHandle.Free(); }
               if (triggerHandle.IsAllocated) { triggerHandle.Free(); }
               if (sensorLabelHandle.IsAllocated) { sensorLabelHandle.Free(); }
               if (pointHandle.IsAllocated) { pointHandle.Free(); }
  
               GC.Collect();
           }
      }
  
  }
  finally
  {
       if (dbf != null)
       {
          dbf.close();
       }
  }                
  
  return eventData;
  }
  </code></pre>