-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Description
C++, generated headers create small struct vectors with incorrect alignment. Seen in AMD/x84 and Mac M1 architectures.
I've traced the bug and it was introduced by this PR: #7520
Also, I've made a fix (#7883), but it seems lost in PRs without issues, so I'm posting the issue to give it more weight.
The issue:
Small structs that are less than uoffset_t in size without any special alignment rules may result in a broken Vector layout that reads back with different values.
Example of the flatbuffers:
// sizeof(JustSmallStruct) == 2
// alignof(JustSmallStruct) == 1
struct JustSmallStruct {
var_0: uint8;
var_1: uint8;
}
table SmallStructs {
small_structs: [JustSmallStruct];
}
now if a Vector of just 3 values of JustSmallStruct: { 2, 1 }, { 3, 1 }, { 4, 1 } is created with FlatBufferBuilder::CreateVectorOfStructs<T>() we get this binary Vector that is when read back get zeros in the first JustSmallStruct item:
03 00 00 00 00 00 02 01 03 01 04 01
^ ^
| |
vector len |
|
followed by two zero bytes of an alignment
that was added because uoffset_t required
4 bytes alignment!?
More confusing is that FlatBufferBuilder::CreateUninitializedVectorOfStructs<T>() method doesn't have this behavior and not adding "2 bytes zeros" before writing the vector len element.
PR with a fix and tests and annotated Flatbuffers that shows the issue is here: #7883