什么类型的错误可能导致对齐被忽略?

时间:2016-05-03 00:57:06

标签: c++ debugging gcc arm alignment

我的光线跟踪器由于未对齐的SIMD NEON操作数而崩溃。我明确地对齐它,但不知何故它在运行时没有正确对齐。相关代码完全如下。运行时,它不可能打印0x7ea3c838,这是8字节对齐,而不是16字节对齐。

Spectrum get_spectrum(Vec3 const& rgb) {
    //...
    static_assert(sizeof(Spectrum)==16,"Implementation error!");
    static_assert(alignof(Spectrum)==16,"Implementation error!");
    Spectrum result;
    printf("%p\n",&result);
    getchar();
    //...
    return result;
}

我尝试在较小的示例中重现错误,但我无法。这让我觉得错误是一些奇怪的内存损坏问题。瓦尔格林德没有帮助;唯一的输出是libarmmem.so来自构造函数std::string::string(char const*)的许多错误,然后由于an endian-swapping optimization导致崩溃(这不是bug,但只是缺乏支持)。

由于我无法在其他地方重现它,我不希望有一个简洁的解决方案。我 寻找的是对可能导致此行为的各种问题的解释。关于如何缩小范围的提示也是受欢迎的。

[更新:我使用内置的GCC / Clang错误检查编译器libasan重新编译了所有代码。总线错误仍然存​​在。]

[更新:我使用Clang重新编译了所有代码。该计划完美无缺。 Hmmmm。]

1 个答案:

答案 0 :(得分:0)

这可能是编译器问题:如果它保证函数入口上的堆栈对齐8并且不检测更严格对齐的数据以根据需要在序言中进行堆栈重新排序,那么事情将如您所述。误差难以再现的事实使得该概率更高。你的static_assert不起作用,因为它检查数据对象的隐含对齐(这是正确的),而不是函数入口上的实际堆栈对齐。

如果你不是编译器开发人员,你绝对不能做任何事情 - 即使是手动内联汇编程序也会在序言扩展和堆栈插槽分配之后进行。

我唯一可以建议的做法是变量static或global。