Problem report: Struct aliasing problem causes Thread_Ready_Chain corruption in 4.6.99.3

Till Straumann strauman at slac.stanford.edu
Tue Dec 5 02:15:55 UTC 2006


Aaron J. Grier wrote:
> On Mon, Dec 04, 2006 at 03:14:49PM -0800, Till Straumann wrote:
>   
>> I believe you would have to declare a union
>>
>> union clumsy_union {
>>    Pbuf                       raw_buffer;
>>    struct udp_packet packet;
>> } xxx;
>>     
>
> unions have enough space to hold all the member datatypes, but is there
> anything in the standard that says that the members actually have to
> occupy the same memory space, or how they are actually overlayed?
>
> K&R says "It is the responsibility of the programmer to keep track of
> what type is currently stored in a union; the results are machine
> dependent if something is stored as one type and extracted as another."
>
> what does c99 say?
>
>   
There is a useful passage (doesn't apply exactly to my example
[punning a char stream into another object] though - for that
kind of operation we need to make assumptions about the
representation of objects on our machine. But hey, we're
implementing an OS here so that is not unreasonable):

Anyways - here's what the standard says about unions
(6.5.2.3 #5):

"One special guarantee is made in order to simplify the use of
unions: if a union contains several structures that share
a common initial sequence, and if the union object currently
contains one of these structures, it is permitted to inspect the
common initial part of any of them anywhere that a declaration
of the complete type of the union is visible..."

I.e., I can say
union packet {
   struct { struct ip_header iph; char data[] } ip_packet;
   struct { struct ip_header iph; struct udp_header udph; char data[]; } 
udp_packet;
} ;

union packet *p;

  if ( p->ip_packet.iph.proto == 17 )
     /* access p->udp_packet here */

>> The problem with this approach is that you don't know upfront that
>> your data is a udp packet.
>>
>> So you'd need unions of all possible variants at each layer of a
>> protocol stack.
>>     
>
> ignoring the union overlay properties mentioned above, couldn't (char *)
> be used as the lowest common denominator? 
sorry - I don't understand. Could you explain?

T.
>  (alignment issues
> notwithstanding.)
>
>   




More information about the users mailing list