Я пытаюсь отладить сбой, который происходит в нашем приложении во время сборки мусора, и просматриваю найденный мной код два связанных фрагмента кода, которые, если не причина проблемы, по крайней мере, вызывают у меня подозрение:
[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) проблему очень сложно воспроизвести. Мне сейчас трудно заставить его вылетать в "старой" версии (где размер структуры неправильный), и я хотел избежать возможного тупика, поскольку каждое тестирование может занять много дней ..