Android NDK:C ++ struct member access,导致SIGBUS(信号SIGBUS:非法对齐)

时间:2017-04-22 13:19:51

标签: c++ struct android-ndk alignment android-studio-2.3

我在Android上移植了一个C ++库(Android Studio 2.3.1 / NDK 25);该库在UWP(VS2017 VC 1.41 - ARM& Win32)定制ARM7板(GCC 4.8)上完美运行。

在Android Studio上进行调试时,在分配给struct成员的过程中,我得到了" SIGBUS(信号SIGBUS:非对齐)" 。 这是结构(我需要它是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 *

我认为它必须由于包装/成员对齐......但是你可以注意到,包装似乎在两个平台上是一致的...仅在Android Studio上,我得到&#34; SIGBUS(信号SIGBUS:非法对齐)&#34;

有人可以帮我理解发生了什么吗? 可能是我错过的编译器开关?这是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")
        }
    }
}

非常感谢!

1 个答案:

答案 0 :(得分:1)

我有完全相同的问题。

在您的代码段中,makesText .| decodeUtf8C .| needsByteString 未对齐,因为它指向secPtr offseted 1(buffer)字节。 (假设sizeof(_t_u8)是对齐的地址)

所有4字节的ailgned内存地址应以'0','4','8'或'C'结尾。由于buffer以'5'结尾,因此未对齐。

ARM处理器支持一些未对齐的内存访问。这就是为什么secPtr合法,但secPtr->crc32 = 0;不合法的原因。

尝试以某种方式删除secPtr->counter= 0;中的1字节偏移,看看问题是否消失。

另请查看此页面以获取详细信息:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html