x86 上可能发生崩溃的原因之一是对齐问题。我的系统上没有 clang 来重现该问题,但我可以在 GCC 的示例中演示它。
如果你做类似的事情:
/* Define a vector type of 16 characters. */
typedef char __attribute__ ((vector_size (16))) byte16;
/* Global pointer. */
char * foo;
byte16 test ()
{
return *(byte16 *)&foo[1];
}
现在,如果您使用以下命令在支持向量的 x86 上编译它:
$ gcc -O3 -march=native -mtune=native a.c
您将获得以下组件用于测试:
test:
movq foo(%rip), %rax
vmovdqa 1(%rax), %xmm0
ret
请注意,移动是对齐的,这当然是错误的。现在,如果您将此函数内联到主函数中,您将得到如下所示的内容:
int main ()
{
foo = __builtin_malloc (22);
byte16 x = *(byte16 *)&foo[1];
return x[0];
}
你会没事的,你会得到不一致的指导。这是一种错误,在编译器中没有很好的修复,因为它需要通过添加新的数据结构等进行过程间优化。
问题的根源在于编译器假设向量类型是对齐的,因此当您取消引用对齐向量类型的数组时,可以使用对齐移动。作为 GCC 中该问题的解决方法,我们可以定义一种未对齐的向量类型,例如:
typedef char __attribute__ ((vector_size (16),aligned (1))) unaligned_byte16;
并用它来取消引用未对齐的内存。
我不确定您在设置中是否遇到了这个问题,但我建议通过检查编译器的程序集输出来检查这一问题。