On Wed, Mar 12, 2008 at 07:19:06AM -0700, Andy Dougherty wrote:
> I haven't been able to track down the problem. I vaguely suspect it's
> an alignment/structure padding issue. Specifically, in the old
> version,
> offsetof(struct parrot_string_t, bufused) == sizeof(Buffer),
> but that wasn't necessarily true in the Preliminary flattened version
> because the padding on the end of Buffer is no longer part of the string
> structure.
>
> This might matter because strings are stored in "bufferlike" pools, but
> I am not confident they are "bufferlike" anymore, since sizeof(Buffer)
> doesn't necessarily mean anything inside the new string structure.
Sounds like it's related to this problem in Perl 5, as explained in a comment
in sv.c:
/* Copying structures onto other structures that have been neatly zeroed
has a subtle gotcha. Consider XPVMG
+------+------+------+------+------+-------+-------+
| NV | CUR | LEN | IV | MAGIC | STASH |
+------+------+------+------+------+-------+-------+
0 4 8 12 16 20 24 28
where NVs are aligned to 8 bytes, so that sizeof that structure is
actually 32 bytes long, with 4 bytes of padding at the end:
+------+------+------+------+------+-------+-------+------+
| NV | CUR | LEN | IV | MAGIC | STASH | ??? |
+------+------+------+------+------+-------+-------+------+
0 4 8 12 16 20 24 28 32
so what happens if you allocate memory for this structure:
+------+------+------+------+------+-------+-------+------+------+...
| NV | CUR | LEN | IV | MAGIC | STASH | GP | NAME |
+------+------+------+------+------+-------+-------+------+------+...
0 4 8 12 16 20 24 28 32 36
zero it, then copy sizeof(XPVMG) bytes on top of it? Not quite what you
expect, because you copy the area marked ??? onto GP. Now, ??? may have
started out as zero once, but it's quite possible that it isn't. So now,
rather than a nicely zeroed GP, you have it pointing somewhere random.
Bugs ensue.
(In fact, GP ends up pointing at a previous GP structure, because the
principle cause of the padding in XPVMG getting garbage is a copy of
sizeof(XPVMG) bytes from a XPVGV structure in sv_unglob)
So we are careful and work out the size of used parts of all the
structures. */
Specifically, I am suspecting that if
offsetof(struct parrot_string_t, bufused) == sizeof(Buffer)
matters, then something is either looking at or copying (sub)structures than
happen to have padding, and in turn that padding happens to end up with bit
patterns that have meaning in some other, larger (containing?) structure.
Nicholas Clark