如何在x86上捕获数据对齐错误(在Sparc上也称为SIGBUS)

时间:2009-12-18 17:19:28

标签: c++ c gcc g++

即使在i386上,是否有可能捕获数据对齐错误?也许通过设置i386特定的机器寄存器或类似的东西。

在Solaris-Sparc上我在这种情况下收到一个SIGBUS,但是在i386上一切都很好。

环境:

  • 32位应用程序
  • Ubuntu Karmic
  • gcc / g ++ v4.4.1

修改: 这就是我问这个问题的原因:

  • 我们的应用程序使用SIGBUS在Sol-Sparc上崩溃。出于调试的目的,我会尝试在i386平台上获得类似的行为。
  • 我们的Sol-sparc机器非常慢,因此编译和调试需要很长时间。我们的i386机器速度令人难以置信(8核,32G内存)。
  • 即使在i386平台上,数据对齐错误也会带来性能损失。因此,我希望尽可能修复数据对齐错误。

6 个答案:

答案 0 :(得分:9)

与此同时,我发现了一个处理此主题的英特尔CPU文档。

请参阅Intel® 64 and IA-32 Architectures Software Developer’s Manual

似乎很难将所有这些东西放在一起。然而,这听起来并非完全不可能。有趣的章节是 4.10.5检查对齐

编辑(上述文件中的一些简明材料):

第5-60页

Interrupt 17 Alignment Check Exception (#AC)

to enable alignment checking, the following conditions must be true:

AM flag is set(bit 18 of control regisster CR0)
AC flag is set (bit 18 of the EFLAGS)
The CPL is 3 (protected mode or virtual-8086 mode).

另外 - 在14.8.2.6中 - 提到内存控制器错误。我不知道它是否只是换句话说:

table 14-11, Encoding of MMM and CCCC Sub-Fields
Address/Command Error  AC  011

答案 1 :(得分:4)

为了扩展Vokuhila-Oliba的答案,看看“SOF Mis-aligned pointers on x86.”线程,似乎gcc可以生成具有错误对齐的内存访问的代码。 AFAIK你无法控制它。

对gcc编译的代码启用对齐检查是个坏主意。您可能会因良好的 C代码而出现SIGBUS错误。

ReEdited:对不起

答案 2 :(得分:3)

我在SOF上找到了一个非常简单的解决方案!请参阅:Mis-aligned pointers on x86

int main(int argc, char **argv)
{
# if defined i386
    /* EDIT: enable AC check */
    asm("pushf; "
    "orl $(1<<18), (%esp); "
    "popf;");
# endif

    char d[] = "12345678";  /* yep! - causes SIGBUS even on Linux-i386 */
    return 0;
}

但我必须承认,我不明白为什么要分配

  

char d [] =“12345678”;

被认为是错位的?

编辑:

在SPARC机器上

char d [] 的赋值行上没有SIGBUS。

答案 3 :(得分:3)

英特尔在支持未对齐的负载方面非常重要。如果我必须在Intel平台上检测到这样的负载,我想我必须修改valgrind以将未对齐的负载视为错误。这样的修改并非易事,但是valgrind的设计理念是用户可以创建新的“工具”。我认为对memcheck工具的简单修改会检测到您的未对齐引用。错误报告非常好。

答案 4 :(得分:1)

许多年后:如果你的gcc / clang足够新(GCC 4.9,clang 3.3?),你可以使用未定义的行为清理程序(-fsanitize=undefined)构建代码,以获取有关未对齐访问的警告给定的平台(但请记住,不同的平台有不同的对齐要求,不同的编译器会选择不同的布局等)。有关详细信息,请参阅https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.htmlhttps://developers.redhat.com/blog/2014/10/16/gcc-undefined-behavior-sanitizer-ubsan/

答案 5 :(得分:0)

英特尔从一开始就建立了不对齐的转让 - 这是x86全新的卖点之一。我理解你想要捕获未对齐访问的原因,但我认为这是不可能的。

编辑:非常高兴被证明是错误的。