Я пытаюсь отладить сбой, который происходит в нашем приложении во время сбора мусора, и, глядя на код, я обнаружил два связанных фрагмента кода, которые, если не являются причиной проблемы, по крайней мере, являются для меня подозрительными:
[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;
Что яя не уверен в том, что во втором случае преобразование из нативной структуры в управляемый ссылочный тип безопасно (обратите внимание, что MilbusData не объявлен как тип значения).
AsЯ сказал, что сбои, которые мы испытываем, происходят обычно во время сбора мусора, но иногда их чрезвычайно трудно воспроизвести.Я дал более подробную информацию о самой аварии в другом вопросе , но здесь я хочу спросить:
- Безопасен ли приведенный выше код?
- А если нет, то может ли это быть причиной управляемой повреждения кучи и объяснить поэтому сбои, которые мы испытываем?
РЕДАКТИРОВАТЬ : я, вероятно, должен был иметьспросил, является ли абсолютно положительным , что проблемы, которые я обнаружил в коде (как несоответствие размеров структуры между собственным и управляемым кодом), могут быть причиной сбоя в GC.Причина для того, чтобы спросить: i) компилятор C # не жалуется на неправильный размер структуры и ii) проблему очень трудно воспроизвести.Я сейчас испытываю трудности в том, чтобы заставить его рухнуть в «старой» версии (где размер структуры неправильный), и я хотел избежать возможного тупика, так как каждое тестирование может занять много дней.