【发布时间】:2011-03-15 20:34:17
【问题描述】:
我们在 HPUX 上,我的代码是 C++。 我们得到了
BUS_ADRALN - 无效的地址对齐
在我们的可执行文件上的一个函数调用。这个错误是什么意思? 相同的功能多次运行,然后突然给出核心转储。 在 GDB 中,当我尝试打印它说不在上下文中的对象值时。 任何线索在哪里检查?
【问题讨论】:
我们在 HPUX 上,我的代码是 C++。 我们得到了
BUS_ADRALN - 无效的地址对齐
在我们的可执行文件上的一个函数调用。这个错误是什么意思? 相同的功能多次运行,然后突然给出核心转储。 在 GDB 中,当我尝试打印它说不在上下文中的对象值时。 任何线索在哪里检查?
【问题讨论】:
大多数处理器(不是 x86 和朋友......家族的黑羊)需要对某些元素的访问以字节的倍数对齐。 IE。如果你从地址 0x04 读取一个整数是可以的,但是如果你尝试从 0x03 做同样的事情,你会导致一个中断被抛出。
这是因为如果加载/存储硬件总是在您正在处理的数据大小的倍数上,那么实现加载/存储硬件会更容易。
由于 HP-UX 仅在 RISC 处理器上运行,而这些处理器通常具有此类限制,您应该在此处查看 -> http://en.wikipedia.org/wiki/Data_structure_alignment#RISC。
【讨论】:
实际上,HP-UX 在 ITRC 上有自己的很棒的论坛,一些 HP 工作人员非常乐于助人。我刚刚看了你问的同一主题和here are some results。例如the similar problem 实际上是由错误的输入参数引起的。我强烈建议您首先阅读类似问题的答案,如有必要,请在此处发布您的问题。
顺便说一句,您可能会被要求发布这些gdb 命令的结果:
(gdb) bt
(gdb) info reg
(gdb) disas $pc-16*8 $pc+16*4
【讨论】:
您遇到了数据对齐问题。这可能是由于尝试通过某种错误的指针进行读取或写入造成的。
数据对齐问题是指针指向的地址未正确“对齐”。例如,某些体系结构(例如旧的 Cray 2)要求任何从内存中读取单个字符以外的任何内容的尝试只能通过指针值的最后 3 位为 0 的指针发生。如果最后一个3 位为 1,硬件将产生对齐错误,这将导致您看到的那种问题。
大多数架构并没有那么严格,而且通常所需的对齐方式取决于所访问的确切类型。例如,32 位整数可能只需要指针的最后 2 位为 0,但 64 位浮点数可能需要最后 3 位为 0。
对齐问题通常是由会导致 SEGFAULT 或分段错误的同一类问题引起的。通常是一个未初始化的指针。但这可能是由于错误的内存分配器没有返回正确对齐的指针,或者是指针类型不正确时指针算术的结果。
malloc 和/或operator new 的系统实现几乎可以肯定是正确的,否则您的程序会在当前崩溃之前崩溃。所以我认为坏内存分配器是最不可能出现的树。我会先检查未初始化的指针,然后检查错误的指针算法。
附带说明,x86 和 x86_64 架构没有任何对齐要求。但是,由于缓存线的工作方式以及其他各种原因,将数据对齐在与存储的数据类型一样大的边界(即 32 位 int 的 4 字节边界)上通常是一个好主意。
【讨论】:
这些问题大部分是由链接到同一库的不同版本的多个上游依赖项引起的。
例如,gnustl 和 stlport 都提供了 C++ 标准库的不同实现。如果您针对 gnustl 进行编译和链接,而您的依赖项之一是针对 stlport 进行编译和链接的,那么您将分别拥有标准函数和类的不同实现。当您的程序启动时,动态链接器将尝试解析所有导出的符号,并会发现偏移量不正确的已知符号,从而产生 BUS_ADRALN 信号。
【讨论】: