[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