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 20:40:37 UTC 2006
Thomas Doerfler (nt) wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Pavel,
>
> you are right, on some targets, my structure definition might get other
> alignments than intended.
>
My attached patch seems to work and does run the sptests on the SPARC.
I am using this structure and managed to remove the casts:
typedef union {
struct {
Chain_Node Node;
void *filler;
} Permanent_Head;
struct {
void *filler;
Chain_Node Node;
} Permanent_Tail;
struct {
Chain_Node *first;
Chain_Node *permanent_null;
Chain_Node *last;
};
} Chain_Control;
> In that case I would like to discuss change the size of the
> "Chain_Control" structure. AFAIK, it has previously been defined to hold
> three pointers to save some memory (the "permanent_null" pointer ist
> shared between the nodes), but maybe it is not SO important. In that
> case, Chain_Control might also be defined as follows:
>
> typedef union {
> struct Chain_Node_struct head;
> struct Chain_Node_struct tail;
> } Chain_Control;
>
> What would get broken if we change to a 16 byte Chain_Control?
>
My first thought is that it would break every operation involving the
first or last element on the list.
What does the chain look like empty? with 1 node? with two nodes?
Does the header get automatically corrected when you go from 2 -> 1
node, from 1 -> 0 nodes?
> Any comments to this?
>
> wkr,
> Thomas.
>
> Pavel Pisa schrieb:
>
>> Hello All,
>>
>> On Tuesday 21 November 2006 13:38, Thomas Doerfler wrote:
>>
>>
>>> As far as I understood the problem, the following two data structures
>>> are used together, but GCC does not understand that they are sometimes
>>> aliased:
>>>
>>> struct Chain_Node_struct {
>>> Chain_Node *next;
>>> Chain_Node *previous;
>>> };
>>>
>>> typedef struct {
>>> Chain_Node *first;
>>> Chain_Node *permanent_null;
>>> Chain_Node *last;
>>> } Chain_Control;
>>>
>>> An example for aliased use is:
>>>
>> ....
>>
>>
>>> Maybe it would help to modify the definition of Chain_Ctronol to
>>> something like:
>>>
>>> typedef union {
>>> struct {
>>> struct Chain_Node_struct head;
>>> void *fill_loc1;
>>> } head_node;
>>>
>>> struct {
>>> void *fill_loc1;
>>> struct Chain_Node_struct tail;
>>> } tail_node;
>>> } Chain_Control;
>>>
>>> The names are NOT good, and surely all chain.c/chain.inl functions would
>>> have to be adapted but this might be a mechanical search/replace procedure.
>>>
>>> Any comments to a change like this?
>>>
>> I have strong feeling that above solution is highly risky.
>> There is no guarantee, that fields order in tail_node would not
>> be reordered. In the fact, there is high probability, that on some
>> targets order would be (4B fill_loc1, 4B spare, 8B tail_node)
>> or tail_node would be reordered to same layout as head_node
>> to follow alignment rules. I have feeling that that new ARM EABI tries
>> to preserve alignment to 8B for example and would expose these problems.
>>
>> The next solutions should work with GCC even, that they are not strictly
>> correct according to C99 (same union should not be accessed trough
>> different pattern than one which is used for it initialization
>> - it no problem for GCC, which is prepared for this use)
>>
>> typedef union {
>> struct {
>> Chain_Node *first;
>> Chain_Node *permanent_null;
>> Chain_Node *last;
>> } control;
>> struct {
>> struct Chain_Node_struct head;
>> } for_alias_marking_only;
>> } Chain_Control;
>>
>> If GCC extension allowing unnamed structures and unions fields
>> is explored, then definition can be changed like next example
>> without any core change requirements
>>
>>
This attached patch uses the unnamed structure and passes all the tests.
What do you think of it?
>> typedef union {
>> struct {
>> Chain_Node *first;
>> Chain_Node *permanent_null;
>> Chain_Node *last;
>> };
>> struct {
>> struct Chain_Node_struct head;
>> } for_alias_marking_only;
>> } Chain_Control;
>>
>> I think, that next solution through explicit pointers typecasting
>> is unsafe
>>
>>
>>
>>> - Chain_Append(&RTEMS_Malloc_GC_list, (Chain_Node *)ptr);
>>> + Chain_Node *node = (Chain_Node *)ptr;
>>> + Chain_Append(&RTEMS_Malloc_GC_list, node);
>>>
>> It has no effect on the aliasing rules implications.
>> It can have effect only due some different compiler
>> resolution/encoding of differently described prescription.
>> But it should lead to exactly same code for optimally optimizing
>> compiler.
>>
>>
I threw this one out. The chain is the problem at hand.
>> Best wishes
>>
>> Pavel Pisa
>> _______________________________________________
>> rtems-users mailing list
>> rtems-users at rtems.com
>> http://rtems.rtems.org/mailman/listinfo/rtems-users
>>
>
>
> - --
> - --------------------------------------------
> IMD Ingenieurbuero fuer Microcomputertechnik
> Thomas Doerfler Herbststrasse 8
> D-82178 Puchheim Germany
> email: Thomas.Doerfler at imd-systems.de
> PGP public key available at:
> http://www.imd-systems.de/pgpkey_en.html
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.2.5 (MingW32)
> Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
>
> iD8DBQFFY1ScwHyg4bDtfjQRAtDcAJsG9spwK7tK0mGEW08boGyvr3jVFACcCM0a
> p2KCBSgOvVOzi/4UjPX1iw8=
> =6B/d
> -----END PGP SIGNATURE-----
> _______________________________________________
> rtems-users mailing list
> rtems-users at rtems.com
> http://rtems.rtems.org/mailman/listinfo/rtems-users
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: chain_casts_2.diff
Type: text/x-patch
Size: 8148 bytes
Desc: not available
URL: <http://lists.rtems.org/pipermail/users/attachments/20061121/a1940b62/attachment-0001.bin>
More information about the users
mailing list