I'm working on some code that serializes cc:PaintOp instances to update a digest [0] for a study [1] -- the idea is the same op should produce the same hash digest.
One issue I ran into is padding -- many of the simpler cc::PaintOp subclasses serialize via memcpy() [2], but some subclasses include padding introduced by the compiler to make the sizeof() word-aligned.
I noticed that this padding is initialized to something like 0xaaaaaa on my out/Default build, but to 0x0 on ASAN / TSAN builds (debugging notes in
crrev.com/c/2288872). This results in test failures, as the calculated digest is different than expected on ASAN / TSAN.
There are 2 issues I want to better understand:
1. First, I wanted to make sure that memcpy() over uninitialized padding doesn't introduce undefined behavior. Some of the discussion in [3] makes me think that there are enough carve-outs in the standard such that this is OK (memcpy() uses char types to copy the padding, so the copied padding has indeterminate values, but we don't encounter undefined behavior). Is this understanding correct?
2. Second -- would we ever see variation in the padding's values on official Chrome builds (the value needs to be the same on Windows, Mac, Android, etc.), or just on ASAN / TSAN builds?
We can declare a char[] for the padding in each PaintOp subclass, use a static_assert(sizeof(foo) == blah) to ensure no additional padding is added, and zero the padding (but only for digest calculation, since the code is hot), but it would be good to know if such changes are necessary or not.
-Caleb