“对齐陷阱”错误意味着什么?
我的一个朋友在尝试调试开始显示“对齐陷阱”错误的代码时遇到了一个大问题。 当特定函数访问全局结构时,会发生此问题。
在对网络进行一些研究之后,仍然不清楚“对齐陷阱”的含义是什么。 有人可以给出一个解释,特别注意通常会导致对齐陷阱的问题以及解决问题的方法(不仅仅是关于如何使用调试器,还有问题本身)?
这一切都是在带有嵌入式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
为对齐值,然后访问它。