[Spread-users] crash bug report

Tim Peters tim at zope.com
Thu Feb 12 12:39:46 EST 2004


[Tim Peters]
>> 1. The effect of the assignment:
>>
>> 	int32		*num_vs_ptr; /* num members in
>> 	num_vs_ptr = &Mess_buf[ num_bytes ];
>>
>> is undefined by C unless the address is properly aligned for an
>> int32.

[Mikhail Terekhov]
> This is not exactly what was in the code before the patch. The code
> was:
>
>                    int32                     *num_vs_ptr;
>                    int32u                     temp;
>                    ....
>                    num_vs_ptr = (int 32 *)&Mess_buf[ num_bytes ];
                                   ^^^^^^^^

That's not legit C.  I assume

                     num_vs_ptr = (int32 *)&Mess_buf[ num_bytes ];

was intended, and that

                     num_vs_ptr = (int32 *)(Mess_buf + num_bytes);

would have been an equivalent spelling.

>                    temp = 1;
>                    memcpy(num_vs_ptr, &temp, sizeof(int32));

I copied two lines from that, because they're the only two that were
relevant to the point I was making there.  Well, the declaration of Mess_buf
is also relevant, to the extent that it's either char * or array of char.

> In this case the assignment to num_vs_ptr is perfectly defined in C.

This is what the current C standard says, section 6.3.2.3, paragraph 7:

    A pointer to an object or incomplete type may be converted to a
    pointer to a different object or incomplete type.  If the resulting
    pointer is not correctly aligned for the pointed-to type, the
    behavior is undefined.

"undefined" means all bets are off:  there's nothing you can say about the
result, and casting char* to int32* clearly falls under this paragraph.
Note that this is a very different case than casting int32* to char*:
*that's* defined.  The other direction isn't.

> It is a pointer to some place inside the buffer Mess_buf.

The standard doesn't support that claim.  It can't, either, because I know
why the standard says this stuff:  there are obscure (type-segregated and
tagged) HW architectures under which the result would in fact not point into
Mess_buf.  I don't know that such architectures are still in actual use, but
the C standards have always catered to such oddities.

> What is undefined is an assignment like *num_vs_ptr = 1 if the pointer
> is not properly aligned.

Yes, that's *also* undefined.

BTW, I had a hard time following this thread:  I understand that gcc
produced segfaults in the original code, and I know why it did (I don't
agree with gcc's decision, on practical grounds, but I can't oppose their
claim that the C standard *allows* what they did -- undefined means
undefined, even to the extent of segfaulting).

Did gcc, or did it not, also produce segfaults under the patched code?  I
didn't see any justification for gcc producing segfaults in the patched
version.





More information about the Spread-users mailing list