packed aligned struct definition causes SIGBUS

1,370 views
Skip to first unread message

Hendy

unread,
Jul 28, 2010, 3:20:46 AM7/28/10
to android-ndk
Hi,

I defined a C++ struct below:

struct STA1Raw
{
uint16_t bigVer;
uint32_t random;
uint32_t smallVer;
uint32_t appId;
uint32_t clientVer;
uint64_t uin;
uint32_t timeStamp;
uint32_t clientIP;
uint8_t savePsw;
uint8_t pswMd5[16];
uint8_t decKey[16];
uint16_t reserved;
}__attribute__((packed));

__attribute__((packed)) is used as I want the struct to be packed
aligned in memory. Because I need to encrypt the whole struct. But
when I assign some value to the first member of the struct, the
process will crash with signal SIGBUS. What I do is:

STA1Raw rawA1;
rawA1.bigVer = htons(1); // SIGBUS here

The codes above run well on some platforms but badly on others. I
wonder if it has something to do with the CPU arch and compiler. If
so, how to make my codes run well on any platforms if I insist using
packed alignment?

I have another question. It seems to have something to do with htons
too. Because if modify the crash line to:

rawA1.bigVer = 256;
or
uint16_t bigVer = htons(1);
rawA1.bigVer = bigVer;

Then everthing is ok. Anyone can explain this?

Any reply will be appreciated.

appforce.org

unread,
Jul 28, 2010, 3:43:27 AM7/28/10
to android-ndk
Have you compared the assembly output of the exact compiler that make
it crash, with another that makes it work? It didn't crash on ADP1
compiled with NDK-r4.

Hendy

unread,
Jul 28, 2010, 4:35:18 AM7/28/10
to android-ndk
No, I didn't compile the codes with different compilers.
I compiled it with NDK-r2 and push the binary to different devices. It
crashed on T-Mobile HTC G1 and T-Mobile Moto Cliq.
> > Any reply will be appreciated.- Hide quoted text -
>
> - Show quoted text -

appforce.org

unread,
Jul 28, 2010, 4:40:19 AM7/28/10
to android-ndk
It didn't crash on my G1 with Android 1.6, compiled both with NDK-r3
and NDK-r4. Maybe you should give a try the newer NDK releases.

David Turner

unread,
Jul 28, 2010, 9:21:34 AM7/28/10
to andro...@googlegroups.com
Yes, some CPUs will crash if you try to access a 16-bit value on a non-aligned 16-bit address (or the same with 32-bits).
This can even change between different ARM-based CPUs. It's an architectural choice, and there is no way to route around it except force the compiler to do *very* costly checks on each memory access.

Packed structures are a bad idea when writing portable code for this very reason. You should instead try to access your packed data as an array of bytes explicitely (or marshal/unmarshal your structs to packed byte arrays for encryption/decryption purposes).


--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.


Olivier Guilyardi

unread,
Jul 28, 2010, 9:39:45 AM7/28/10
to andro...@googlegroups.com
Since this can cause hard to reproduce bugs, I think it would be smart if the
NDK issued a warning or error whenever the packed attribute is used.

Olivier

> <mailto:andro...@googlegroups.com>.


> To unsubscribe from this group, send email to
> android-ndk...@googlegroups.com

> <mailto:android-ndk%2Bunsu...@googlegroups.com>.

David Turner

unread,
Jul 28, 2010, 9:51:08 AM7/28/10
to andro...@googlegroups.com
On Wed, Jul 28, 2010 at 6:39 AM, Olivier Guilyardi <li...@samalyse.com> wrote:
Since this can cause hard to reproduce bugs, I think it would be smart if the
NDK issued a warning or error whenever the packed attribute is used.


This would be a compiler feature, and if there is no specific GCC flag to do that (-Wpacked exists but does something really different).

Olivier Guilyardi

unread,
Jul 28, 2010, 11:54:11 AM7/28/10
to andro...@googlegroups.com
On 07/28/2010 03:51 PM, David Turner wrote:
>
>
> On Wed, Jul 28, 2010 at 6:39 AM, Olivier Guilyardi <li...@samalyse.com
> <mailto:li...@samalyse.com>> wrote:
>
> Since this can cause hard to reproduce bugs, I think it would be
> smart if the
> NDK issued a warning or error whenever the packed attribute is used.
>
>
> This would be a compiler feature, and if there is no specific GCC flag
> to do that (-Wpacked exists but does something really different).

I see. Actually, thinking again about this, it looks like this may be a GCC bug,
because it compiles to something which may not run on certain ARM CPUs, without
a single warning.

--
Olivier

fadden

unread,
Jul 28, 2010, 3:48:55 PM7/28/10
to android-ndk
On Jul 28, 8:54 am, Olivier Guilyardi <l...@samalyse.com> wrote:
> I see. Actually, thinking again about this, it looks like this may be a GCC bug,
> because it compiles to something which may not run on certain ARM CPUs, without
> a single warning.

Consider:

struct {
int16_t first;
int32_t second;
int64_t third;
} __attribute__((packed)) blah;
printf("storing first %p\n", &blah.first);
blah.first = 1;
printf("storing second %p\n", &blah.second);
blah.second = 2;
printf("storing third %p\n", &blah.third);
blah.third = 3;
printf("stored\n");

This results in:

storing first 0xbe97bce8
storing second 0xbe97bcea
storing third 0xbe97bcee
stored

If you look at the object code generated by gcc, it's using STRH (half-
word store) instead of STR because it knows the struct members are
unaligned. If you remove the "packed", the code generation changes to
STR.

If you remove the "packed", and try to do the above on an unaligned
address, you will see something like:

storing first 0xbed96cd9
storing second 0xbed96cdd
storing third 0xbed96ce1
[1] Bus error atomic

Unaligned 16-bit and 32-bit stores work on all of the Android devices
I know of, but unaligned 64-bit accesses will fail *unless*, as seen
earlier, the compiler knows about them and can adjust its codegen
appropriately.

Hendy

unread,
Jul 28, 2010, 11:13:18 PM7/28/10
to android-ndk
Thanks for all your guys' replies and constructive suggestions.

Yes, indeed the same time I post here, I decide to modify my codes to
remove the packed attribute and pack the structrue to a continuous
memory myself.

It's just the weird behaviours puzzled me. Becides what I mentioned
above, such as the htons problem, I have tried to compile with new
versions of NDK as appforce.org suggrested. And sometimes it ran well
while sometimes it crashed. And because I used the modifed NDK version
by Dmitry: http://www.crystax.net/android/ndk.php. Sometimes when STL
is used it crashed. Seems to be irregular.

Anyway, I should not use packed attribute when define a structure.

On Jul 28, 9:51 pm, David Turner <di...@android.com> wrote:
> On Wed, Jul 28, 2010 at 6:39 AM, Olivier Guilyardi <l...@samalyse.com>wrote:
>
> > Since this can cause hard to reproduce bugs, I think it would be smart if
> > the
> > NDK issued a warning or error whenever the packed attribute is used.
>
> This would be a compiler feature, and if there is no specific GCC flag to do
> that (-Wpacked exists but does something really different).
>
>
>
> > Olivier
>
> > On 07/28/2010 03:21 PM, David Turner wrote:
> > > Yes, some CPUs will crash if you try to access a 16-bit value on a
> > > non-aligned 16-bit address (or the same with 32-bits).
> > > This can even change between different ARM-based CPUs. It's an
> > > architectural choice, and there is no way to route around it except
> > > force the compiler to do *very* costly checks on each memory access.
>
> > > Packed structures are a bad idea when writing portable code for this
> > > very reason. You should instead try to access your packed data as an
> > > array of bytes explicitely (or marshal/unmarshal your structs to packed
> > > byte arrays for encryption/decryption purposes).
>
> > >     android-ndk...@googlegroups.com<android-ndk%2Bunsubscribe@googlegr­oups.com>
> > >     <mailto:android-ndk%2Bunsu...@googlegroups.com<android-ndk%252Bunsubscr­i...@googlegroups.com>
> > >.
> > >     For more options, visit this group at
> > >    http://groups.google.com/group/android-ndk?hl=en.
>
> > > --
> > > You received this message because you are subscribed to the Google
> > > Groups "android-ndk" group.
> > > To post to this group, send email to andro...@googlegroups.com.
> > > To unsubscribe from this group, send email to
> > > android-ndk...@googlegroups.com<android-ndk%2Bunsubscribe@googlegr­oups.com>
> > .
> > > For more options, visit this group at
> > >http://groups.google.com/group/android-ndk?hl=en.
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "android-ndk" group.
> > To post to this group, send email to andro...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > android-ndk...@googlegroups.com<android-ndk%2Bunsubscribe@googlegr­oups.com>
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/android-ndk?hl=en.- Hide quoted text -

Hendy

unread,
Jul 28, 2010, 11:21:09 PM7/28/10
to android-ndk
Hi, fadden

How do you think to solve this problem? As discussed above, packed
aligned definition may cause bus error and you say unaligned 64-bit
access will fail too. Then how to make the two work fine together.
Will it be ok if force the structure to be 16-bit or 32-bit aligned?

Angus Lees

unread,
Jul 28, 2010, 8:07:35 PM7/28/10
to andro...@googlegroups.com
It looks to my relatively uneducated eye like the original poster is doing everything correctly and the compiler should be generating the correct (possibly slower) instructions for safe unaligned access.
Surely this is a compiler bug, or a bug in the htons macro?  Other posts in this thread seem to be suggesting otherwise, so I'm confused ...

Hendy: have you disassembled and compared a working and non-working version?

 - Gus

Olivier Guilyardi

unread,
Jul 29, 2010, 12:50:51 PM7/29/10
to andro...@googlegroups.com
All in all, I think there two main possibilities:
- or this is a NDK bug, where the compiler is not set up properly, and think it
generates valid instructions
- or this is a compiler bug

In both cases I think it would be worth to discuss this with the gcc devs, so
that it eventually gets fixed if this is a bug in gcc, or that they point out
the problem in the gcc command line, if this is a NDK bug.

Olivier

Reply all
Reply to author
Forward
0 new messages