Может ли этот код вызвать повреждение управляемой кучи?

Я пытаюсь отладить сбой, который происходит в нашем приложении во время сборки мусора, и просматриваю найденный мной код два связанных фрагмента кода, которые, если не причина проблемы, по крайней мере, вызывают у меня подозрение:

[StructLayout(LayoutKind.Sequential, Size = 96, CharSet = CharSet.Ansi, Pack=1)]
public class MilbusData
{
  public System.Int64 TimeStamp;
  public System.Int16 Lane;
  public System.Int16 TerminalAddress;
  public System.Int16 TerminalSubAddress;
  public System.Int16 Direction;   
  public System.Int64 ErrorCounter;   
  public System.Int64 MessageCounter;   
  public System.Int16 RTErrorState;     
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
  public System.UInt16[] Data;
}

Обратите внимание, что, насколько я понимаю, структура фактически имеет размер не менее 98 байт, но объявлена ​​как длина 96 байт (код хотя компилируется).

Второй подозрительный фрагмент кода связан с приведенной выше структурой:

MilbusData^ ret = nullptr;
if (m_Stream->Read(m_RawData, 0, sizeof(TMilbusData)) == sizeof(TMilbusData))
{
  GCHandle pinnedRawData = GCHandle::Alloc(m_RawData, GCHandleType::Pinned);

  ret = (MilbusData^)Marshal::PtrToStructure(pinnedRawData.AddrOfPinnedObject(), 
                                             MilbusData::typeid);

   pinnedRawData.Free();
}

где m_RawData - это простой байтовый массив без знака, а TMilbusData - это C ++ (собственный) код, аналогичный приведенной выше структуре, определенный как

typedef struct
{
  __int64 TimeStamp;
  short Lane;
  short TerminalAddress;
  short TerminalSubAddress;
  short Direction;
  __int64 ErrorCounter;
  __int64 MessageCounter;
  short RTErrorState;
  unsigned char Data[64];
} TMilbusData;

What I ' m не уверен во втором случае, является ли преобразование из собственной структуры в управляемый ссылочный тип безопасным (обратите внимание, что MilbusData не объявлен как тип значения).

Как я уже сказал, сбои, с которыми мы сталкиваемся, обычно происходят во время сборки мусора, но иногда их чрезвычайно трудно воспроизвести. Я дал более подробную информацию о самом сбое в другом вопросе , но вот что я хочу задать здесь:

  • Безопасен ли приведенный выше код?
  • А если нет, может ли это быть причиной повреждения управляемой кучи и объяснить, таким образом, сбои, с которыми мы сталкиваемся?

РЕДАКТИРОВАТЬ : Мне, наверное, следовало спросить, абсолютно положительно что проблемы, которые я обнаружил в коде (например, несоответствие размеров структур нативного и управляемого кода), могут быть причиной сбоя в сборщике мусора. Причина вопроса: i) компилятор C # не жалуется на неправильный размер структуры и ii) проблему очень сложно воспроизвести. Мне сейчас трудно заставить его вылетать в "старой" версии (где размер структуры неправильный), и я хотел избежать возможного тупика, поскольку каждое тестирование может занять много дней ..

5
задан Community 23 May 2017 в 11:45
поделиться