Skip to Main Content

DevOps, CI/CD and Automation

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

need CC flag to align structs on stack

807575Aug 13 2002 — edited Aug 15 2002
I get a SIGBUS casting sockaddr to sockaddr_in,
but only if sockaddr was declared on the stack.
I am using Forte C/C++ for Sparc WS6U2.

Getting right to the point, is there a way to have
the compiler strictly align structs declared on the
stack, similar to malloc always returning strictly
aligned memory?

Is there any other workaround, other than using
-misalign (bad performance), or fixing each and
every instance of a struct on the stack?
This seems like such a common scenario that
a reasonable workaround should be available.

Thanks in advance,
-Ralph

Details follow...

The following code fragment contains an alignment bug
when casting a sockaddr to a sockaddr_in. The bug
occurs when the sockaddr is declared on the stack, but
not if it is malloc'd. While a call to malloc will return
strictly aligned memory, simply declaring a struct on
the stack will cause it to be aligned only as strictly as
is necessary according to the struct definition. Since
sockaddr requires only short aligned memory, later
casting it to sockaddr_in (a very very frequent case)
is dangerous because it requires long aligned memory.

The sockaddr only requires short alignment, since the
sa_family_t is a short, and the generic address is an
array of char.

However, the sockaddr is very very frequently cast into
a sockaddr_in, which requires long alignment, since the
IPv4 address can be viewed as a 32-bit unsigned integer.

/usr/include/sys/socket.h:
struct sockaddr {
sa_family_t sa_family; /* address family */
char sa_data[14]; /* up to 14 bytes of direct address */
};

/usr/include/netinet/in.h
struct sockaddr_in {
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};

struct in_addr {
union {
struct { uint8_t s_b1, s_b2, s_b3, s_b4; } Sun_b;
struct { uint16_t s_w1, s_w2; } Sun_w;
in_addr_t Saddr;
} Sun;
};

int SomeClass::SendViaSocket( char *pszMessage )
{
// some code

struct sockaddr Socket;

// some code

SetIPv4SocketAddress( &Socket );

// some code
}

void SomeClass::SetIPv4SocketAddress( struct sockaddr *pSocket )
{
// some code

memset( pSocket, 0, sizeof(*pSocket) );

struct sockaddr_in pIPv4Socket = (struct sockaddr_in)pSocket;

pIPv4Socket->sin_family = AF_INET;
pIPv4Socket->sin_port = htons((unsigned short)nPort);
pIPv4Socket->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
// SIGBUS occurs, sometimes, if the moon is full, in previous line

// some code
}
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Sep 12 2002
Added on Aug 13 2002
7 comments
242 views