From 38d4f6e67975e1c0b77c86295c9939b16c7ba2e5 Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Tue, 24 Jul 2018 12:19:59 -0700 Subject: [PATCH] Fix mscordbi metadata reader alignment bug on Linux. (dotnet/coreclr#19070) Works fine on Windows minidumps, but on Linux (via OpenVirtualProcess for production breakpoints and future core dumps) the compiler's struct alignment rules are different. On Windows, classes/structs are aligned based on the largest field. On Linux, they are 4 byte aligned regardless of the field sizes. https://github.com/dotnet/coreclr/issues/17692 Commit migrated from https://github.com/dotnet/coreclr/commit/e6ada167d7991b1ab6e1ea921c521a691610e269 --- src/coreclr/src/md/datasource/datatargetreader.cpp | 6 ++++++ src/coreclr/src/md/datasource/targettypes.cpp | 3 +++ 2 files changed, 9 insertions(+) diff --git a/src/coreclr/src/md/datasource/datatargetreader.cpp b/src/coreclr/src/md/datasource/datatargetreader.cpp index 03b9811..3c32f61 100644 --- a/src/coreclr/src/md/datasource/datatargetreader.cpp +++ b/src/coreclr/src/md/datasource/datatargetreader.cpp @@ -163,7 +163,13 @@ void DataTargetReader::Align(DWORD alignmentBytes) void DataTargetReader::AlignBase() { +#ifdef _MSC_VER + // Windows MSVC compiler aligns structs based on the largest field size Align(m_currentStructureAlign); +#else + // clang (on all platforms) aligns structs always on 4 byte boundaries + Align(4); +#endif } HRESULT DataTargetReader::GetRemotePointerSize(ULONG32* pPointerSize) diff --git a/src/coreclr/src/md/datasource/targettypes.cpp b/src/coreclr/src/md/datasource/targettypes.cpp index 9af7dd1..cb6b8a1 100644 --- a/src/coreclr/src/md/datasource/targettypes.cpp +++ b/src/coreclr/src/md/datasource/targettypes.cpp @@ -134,9 +134,12 @@ m_tableMax(0) HRESULT Target_MapSHash::ReadFrom(DataTargetReader & reader) { HRESULT hr = S_OK; + // Only the Windows MSVC compiler does this; not clang on Linux +#ifdef _MSC_VER IfFailRet(reader.Skip8()); // this byte gets used by the base class even though it has no members // I'm guessing this is so the 2nd base class (noncopyable) doesn't start at the same // location, but I can't be sure. Whatever the cause, the layout skips a byte. +#endif // _MSC_VER IfFailRet(reader.ReadPointer(&m_table)); IfFailRet(reader.Read32(&m_tableSize)); IfFailRet(reader.Read32(&m_tableCount)); -- 2.7.4