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

Reply via email to