Fwd: Problem report: Struct aliasing problem causes Thread_Ready_Chain corruption in 4.6.99.3
Joel Sherrill
joel.sherrill at oarcorp.com
Tue Nov 21 21:42:39 UTC 2006
Till Straumann wrote:
> **BEWARE**
>
> Thomas is right. And after reading the aforementioned article
> I tried their example (simplified):
>
> inline void
> writethree(int *p)
> {
> short *palias = (short*)p;
> /* compiler assumes 'palias' and 'p' *dont* address the same memory
> region */
> *palias = 3;
> }
>
> int
> testalias()
> {
> int value = 0xdeadbeef;
> writethree(&value);
> return value;
> }
>
> When I compile (gcc-4.1.2, gcc-4.1.1) this with
>
> -fstrict-aliasing -O -Wstrict-aliasing=2
>
> then the call to 'writethree' gets optimized away
> **w/o warning** (since 'palias' is not a valid alias of 'p').
>
>
I just compiled one of the sparc BSPs with all tests enabled and got
243 warnings with -Wstrict-alias=2
63 warnings without -Wstrict-alias=2
That's just one BSP and one arbitrary set of libcpu and libbsp code. There
are about 90 BSPs when you count variations so there is a lot of uncompiled
code let to give more warnings.
I am beginning to be very scared of making a release with this
strict-alias enabled.
On one hand, there has been a LOT of successful testing and on the
other, there is
Peer's edge condition where something broke in a painful manner. And we
know
testing does not prove the absence of errors only the ability of our tests.
Ralf.. to be conservative, let's turn off strict-alias'ing for 4.7 and 4.8.
In addition, turn on -Wstrict-alias=2 for 4.8. Hopefully we can resolve the
warnings and work from there.
Peer.. I would appreciate it if you could use my last patch and see if
it generates
correct code in your situation. If it does, I will see if I can get a
ruling from
some gcc person on how dangerous the code is for the future.
> I must admit that I didn't fully understand the
> strict-alias rule until today and I'm a bit shocked.
> I'm sure it breaks code I've written.
>
>
It seems like it could break a lot of device drivers and communications
protocol code. The above type of code isn't that hard to find in device
drivers.
> Until every cast has been hand-checked carefully
> I see no way around -fno-strict-aliasing
>
> (And, yes, the 'intermediate variable fix' seems to
> not fix anything except silencing the warning).
>
> If gcc sees enough of the source code (e.g. when inlining)
> to know exactly what the 'original' pointers were
> (prior to any casting and using intermediate variables)
> then it 'ruthlessly' enforces aliasing rules no
> matter what casting you do:
>
> Consider this:
>
> typedef union {
> int i;
> short s;
> } u2;
>
> int rtn3()
> {
> int rval = 3;
> u2 *pu = &rval;
> short *ps = (short*)pu;
> *ps = 0xdead;
> return rval;
> }
>
> Even though casting a int* into u2* is legal
> (u2 contains a int member) and u2* to short*
> is, too (u2 also contains a short member)
> gcc still optimizes *ps=0xdead away because
> it says: at the end of the day, ps must not be
> an alias of &rval and it knows that both
> point to the same address.
> OTOH, setting
>
> pu->s = 0xdead;
>
> would not go away.
>
> If code was not written from the ground up with the
> strict-aliasing rule in mind then it seems hard to
> ensure the rule is not violated.
>
> -- Till
>
> Thomas Doerfler wrote:
>
>> Ralf,
>>
>> Ralf Corsepius schrieb:
>>
>>
>>> On Tue, 2006-11-21 at 16:38 +0100, Thomas Doerfler wrote:
>>>
>>>
>>>
>>>> Therefore your patch in malloc.c is IMHO identical to the previous
>>>> explicit cast.
>>>>
>>>>
>>> Please prove Joel's patch to be broken.
>>>
>>>
>> maybe it is my limited horizon, but I don't see the difference applied
>> by the following patch:
>>
>> if (_System_state_Is_up(_System_state_Get())) {
>> if ((_Thread_Dispatch_disable_level > 0) || (_ISR_Nest_level > 0)) {
>> - Chain_Append(&RTEMS_Malloc_GC_list, (Chain_Node *)ptr);
>> + Chain_Node *node = (Chain_Node *)ptr;
>> + Chain_Append(&RTEMS_Malloc_GC_list, node);
>> return;
>>
>> The intermediate local variable "node" can easily be optimized by the
>> compiler. For the compiler, it should be obvious, that "node" is a
>> direct alias for "(Chain_Node *)ptr". So I don't see ANY reason, what
>> this additional variable would change in the compiler's behavior.
>>
>> It MAY BE, that this change produces different code, but I don't see,
>> why the code should be more correct.
>>
>> wkr,
>> Thomas.
>>
>>
>>
>>> Ralf
>>>
>>>
>>>
>>>
>>
>>
>
> _______________________________________________
> rtems-users mailing list
> rtems-users at rtems.com
> http://rtems.rtems.org/mailman/listinfo/rtems-users
>
More information about the users
mailing list