I'm porting a C++ library on Android (Android Studio 2.3.1/NDK 25); the library works flawlessly on UWP (VS2017 VC 1.41 - ARM & Win32) a custom ARM7 board (GCC 4.8).
When debugging on Android Studio, I get a "SIGBUS (signal SIGBUS: illegal alignment)" during an assignment to a struct member. Here is the struct (I need it to be 64-bit aligned):
typedef unsigned int _t_u32; // 32-bit unsigned
typedef unsigned long long _t_u64; // 64-bit unsigned
typedef struct __attribute__((aligned(8)))
{
_t_u32 crc32;
_t_u64 counter;
} t_security;
Now, here is the code snippet:
void prepareBuffer(_t_u8 cmd, _t_u8 *buffer, _t_u32 buffferLen)
{
t_security *secPtr = ((t_security *)(buffer + sizeof(_t_u8)));
secPtr->crc32 = 0;
secPtr->counter= 0; << when this is being executed, on Android Studio-only, I get *"SIGBUS (signal SIGBUS: illegal alignment)"*
...
...
}
From Android Studio debugger watches:
sizeof(t_security) = {unsigned int} 16
&secPtr = {t_security * | 0xdc98eb41} 0xdc98eb41
&secPtr->crc32 = {_t_u32 * | 0xdc98eb41} 0xdc98eb41
&secPtr->counter = {_t_u64 * | 0xdc98eb49} 0xdc98eb49
From Visual Studio debugger watches (ARM platform):
sizeof(t_security) 16 unsigned int
secPtr 0x00afe2e5 {crc32=3435973836 ...} t_security *
&secPtr->crc32 0x00afe2e5 {3435973836} unsigned int *
&secPtr->counter 0x00afe2ed {14757395258967641292} unsigned __int64 *
I suppose it has to due to packing/member alignment... but as you can notice, the packaging seems consistent on the two platforms... just on Android Studio-only, I get "SIGBUS (signal SIGBUS: illegal alignment)".
Can someone please help me understand what's going on? May be a compiler switch I'm missing? Here's the ndk's gradle config:
android.ndk {
moduleName = "NativeLib"
// add compilation flags
cppFlags.add("-DANDROID")
cppFlags.add("-frtti")
cppFlags.add("-std=c++14")
cppFlags.add("-fexceptions")
// include headers
cppFlags.add("-I${file("native-src")}".toString())
ldLibs.addAll("android", "dl", "log", "z", "atomic")
stl = "c++_static" // LLVM compiler
}
android.buildTypes {
all {
// To solve struct packing issues, setting abiFilters to package only 32-bit architectures:
ndk.with {
abiFilters.add("armeabi")
abiFilters.add("armeabi-v7a")
abiFilters.add("mips")
abiFilters.add("x86")
}
}
debug {
ndk.with {
cppFlags.add("-DDEBUG")
CFlags.add("-DDEBUG")
}
}
}
Many thanks!
I had exactly the same issue.
In your code snippet,
secPtr
is not aligned because it points tobuffer
offseted by 1(sizeof(_t_u8)
) byte. (assuming thatbuffer
is aligned address)All 4-byte ailgned memory addresses should end in '0', '4', '8' or 'C'. Since
secPtr
ends in '5', it is not aligned.ARM processors support some of unaligned memory access. That is why
secPtr->crc32 = 0;
is legal, butsecPtr->counter= 0;
is not.Try removing 1-byte offset in
secPtr
somehow and see if the problem goes away.Also check out this page for detailed information: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html