“对齐陷阱”错误意味着什么?

我的一个朋友在尝试调试开始显示“对齐陷阱”错误的代码时遇到了一个大问题。 当特定函数访问全局结构时,会发生此问题。

在对网络进行一些研究之后,仍然不清楚“对齐陷阱”的含义是什么。 有人可以给出一个解释,特别注意通常会导致对齐陷阱的问题以及解决问题的方法(不仅仅是关于如何使用调试器,还有问题本身)?

这一切都是在带有嵌入式Linux的ARM处理器(OMAP L138)的C代码中完成的。

注意:我不是试图通过这个答案获得特定于错误的解决方案建议,但是,正如问题标题所示,理解“对齐陷阱”错误意味着什么。 这就是我不打算放置源代码等的原因。

它是操作系统和处理器特定的(也是特定于ABI的 )。

你有一些内存损坏 ,或内存泄漏或缓冲区溢出等…,或者你正在解除引用一些坏指针(未初始化或错误地计算) – 例如指向double的指针,它不是8的倍数(或者,一些体系结构,指向int的指针,它不是4的多个,或者你可能跳转到一些无效的地址(例如,到一个坏的函数指针)。

在Linux上,我建议使用gcc -Wall -g进行编译并使用调试器( gdb )和valgrind 。 您可能对使用-fsanitize=address-fsanitize=undefined编译标志(使用GCC 4.9)感兴趣。 它们都是仪器(如此修改)生成的代码。

阅读有关未定义的行为 。 你肯定得到了一些。

无论何时进行未对齐访问,ARM都会触发对齐陷阱。 什么是未对齐访问? 当访问多字节值时,其指针不是其对齐的倍数,例如,当通过解除引用非4的倍数来访问uint32_t时。

如果你有__attribute__((packed))数据结构,你可以得到它们:

 struct foo { uint8_t a; uint32_t b; } __attribute__((packed)); 

b访问将是未对齐的,因此将导致对齐陷阱。 您必须将数据memcpy为对齐值,然后访问它。