I’m trying to figure out a crash that only happens in a 32-bit ARM build of my code (well, in a C library my code uses.) The crash is an unaligned memory access: EXC_BAD_ACCESS (code=EXC_ARM_DA_ALIGN, address=0x18083b34) during a 64-bit load from a non-8-byte-aligned address. The instruction that crashed is ldrexd r1, r2, [r0] where r0= 0x18083b34. (This is part of code generated by the compiler intrinsic __sync_add_and_fetch.)
The part I don’t understand is why the address isn’t aligned — it’s declared as a uint64_t: typedef struct { union { volatile uint64_t val_64; // <— this is what r0 points to volatile uint32_t val_32; volatile uint16_t val_16; volatile uint8_t val_8; } value; } atomic_val_t;
The atomic_val_t in question is itself a member of a larger structure that was allocated by malloc.
Shouldn’t C alignment rules dictate that the ‘value’ union and the surrounding ‘atomic_val_t’ type be 8-byte-aligned, since they contain a 64-bit integer? And if they don’t, what’s the workaround to ensure safe alignment?
—Jens |