Android NDK:C++ 结构成员访问,导致 SIGBUS(信号 SIGBUS:非法对齐)
Android NDK: C++ struct member access, causes SIGBUS (signal SIGBUS: illegal alignment)
我正在 Android (Android Studio 2.3.1/NDK 25) 上移植一个 C++ 库;该库在 UWP (VS2017 VC 1.41 - ARM & Win32) 自定义 ARM7 板 (GCC 4.8) 上完美运行。
在 Android Studio 上调试时,我在分配给结构成员期间得到 "SIGBUS (signal SIGBUS: illegal alignment)"。
这是结构(我需要它是 64 位对齐的):
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;
现在,这是代码片段:
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)"*
...
...
}
来自 Android Studio 调试器手表:
sizeof(t_security) = {unsigned int} 16
&secPtr = {t_security * | 0xdc98eb41} 0xdc98eb41
&secPtr->crc32 = {_t_u32 * | 0xdc98eb41} 0xdc98eb41
&secPtr->counter = {_t_u64 * | 0xdc98eb49} 0xdc98eb49
来自 Visual Studio 调试器手表(ARM 平台):
sizeof(t_security) 16 unsigned int
secPtr 0x00afe2e5 {crc32=3435973836 ...} t_security *
&secPtr->crc32 0x00afe2e5 {3435973836} unsigned int *
&secPtr->counter 0x00afe2ed {14757395258967641292} unsigned __int64 *
我想这是由于 packing/member 对齐...但正如您所注意到的,包装在两个平台上似乎是一致的...只是在 Android Studio-only 上,我得到 "SIGBUS (signal SIGBUS: illegal alignment)".
有人可以帮我理解这是怎么回事吗?
可能是我缺少的编译器开关?这是 ndk 的 gradle 配置:
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")
}
}
}
非常感谢!
我遇到了完全相同的问题。
在您的代码片段中,secPtr
未对齐,因为它指向偏移了 1(sizeof(_t_u8)
) 个字节的 buffer
。 (假设buffer
是对齐地址)
所有 4 字节的内存地址都应以“0”、“4”、“8”或 'C' 结尾。由于 secPtr
以“5”结尾,因此未对齐。
ARM 处理器支持一些未对齐的内存访问。这就是 secPtr->crc32 = 0;
合法而 secPtr->counter= 0;
不合法的原因。
尝试以某种方式删除 secPtr
中的 1 字节偏移量,看看问题是否消失。
另请查看此页面以获取详细信息:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html
我正在 Android (Android Studio 2.3.1/NDK 25) 上移植一个 C++ 库;该库在 UWP (VS2017 VC 1.41 - ARM & Win32) 自定义 ARM7 板 (GCC 4.8) 上完美运行。
在 Android Studio 上调试时,我在分配给结构成员期间得到 "SIGBUS (signal SIGBUS: illegal alignment)"。 这是结构(我需要它是 64 位对齐的):
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;
现在,这是代码片段:
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)"*
...
...
}
来自 Android Studio 调试器手表:
sizeof(t_security) = {unsigned int} 16
&secPtr = {t_security * | 0xdc98eb41} 0xdc98eb41
&secPtr->crc32 = {_t_u32 * | 0xdc98eb41} 0xdc98eb41
&secPtr->counter = {_t_u64 * | 0xdc98eb49} 0xdc98eb49
来自 Visual Studio 调试器手表(ARM 平台):
sizeof(t_security) 16 unsigned int
secPtr 0x00afe2e5 {crc32=3435973836 ...} t_security *
&secPtr->crc32 0x00afe2e5 {3435973836} unsigned int *
&secPtr->counter 0x00afe2ed {14757395258967641292} unsigned __int64 *
我想这是由于 packing/member 对齐...但正如您所注意到的,包装在两个平台上似乎是一致的...只是在 Android Studio-only 上,我得到 "SIGBUS (signal SIGBUS: illegal alignment)".
有人可以帮我理解这是怎么回事吗? 可能是我缺少的编译器开关?这是 ndk 的 gradle 配置:
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")
}
}
}
非常感谢!
我遇到了完全相同的问题。
在您的代码片段中,secPtr
未对齐,因为它指向偏移了 1(sizeof(_t_u8)
) 个字节的 buffer
。 (假设buffer
是对齐地址)
所有 4 字节的内存地址都应以“0”、“4”、“8”或 'C' 结尾。由于 secPtr
以“5”结尾,因此未对齐。
ARM 处理器支持一些未对齐的内存访问。这就是 secPtr->crc32 = 0;
合法而 secPtr->counter= 0;
不合法的原因。
尝试以某种方式删除 secPtr
中的 1 字节偏移量,看看问题是否消失。
另请查看此页面以获取详细信息:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html