禁止在x86 / x86_64上进行未对齐的内存访问

时间:2012-08-06 23:57:29

标签: linux debugging x86 memory-alignment

我想在x86 / x86_64上使用禁止的未对齐内存访问来模拟系统。 是否有一些调试工具或特殊模式来执行此操作?

在使用为SPARC或其他类似CPU设计的软件(C / C ++)时,我想在几台x86 / x86_64 PC上运行许多(CPU密集型)测试。但是我对Sparc的访问是有限的。

据我所知,Sparc总是检查内存读写中的对齐是否自然(从任何地址读取一个字节,但只有当地址可以被4整除时才允许读取4字节字)。

可能是Valgrind还是PIN有这样的模式?还是特殊的编译模式? 我正在寻找Linux非商业工具,但也允许使用Windows工具。

或者可能是EFLAGS中有秘密的CPU标志?

4 个答案:

答案 0 :(得分:7)

我刚刚阅读了与维基百科文章Does unaligned memory access always cause bus errors?相关的问题Segmentation Fault

在文章中,有一个非常罕见的Intel processor flags AC aka对齐检查的精彩提醒。

以下是如何启用它(来自Segmentation Fault):

#if defined(__GNUC__)
# if defined(__i386__)
    /* Enable Alignment Checking on x86 */
    __asm__("pushf\norl $0x40000,(%esp)\npopf");
# elif defined(__x86_64__) 
     /* Enable Alignment Checking on x86_64 */
    __asm__("pushf\norl $0x40000,(%rsp)\npopf");
# endif
#endif

一旦启用它就像/proc/cpu/alignment中的ARM对齐设置一样工作,请参阅答案How to trap unaligned memory access?以获取示例。

此外,如果您正在使用GCC,我建议您启用-Wcast-align警告。在为具有严格对齐要求(例如ARM)的目标构建时,GCC将报告可能导致未对齐内存访问的位置。

答案 1 :(得分:5)

这很棘手,我没有亲自完成,但我认为你可以通过以下方式完成:

x86_64 CPU(特别是我已经检查过Intel Corei7,但我猜其他人也有)有一个性能计数器MISALIGN_MEM_REF,用于计算未对齐的内存引用。

首先,您可以运行您的程序并使用Linux下的“perf”工具来计算您的代码所执行的错位访问次数。

更棘手和有趣的黑客是编写一个内核模块,该模块对性能计数器进行编程,以便在溢出时生成中断并使其溢出第一个未对齐的加载/存储。在内核模块中响应此中断,但向您的进程发送信号。

这实际上会将x86_64转变为不支持未对齐访问的核心。

这不会很简单 - 除了代码之外,系统库还使用未对齐的访问,因此将它们与您自己的代码分开会很棘手。

答案 2 :(得分:4)

GCC 和 Clang 都内置了 UndefinedBehaviorSanitizer。其中一项检查 alignment 可以通过 -fsanitize=alignment 启用。它将发出代码以在运行时检查指针对齐情况,并在取消引用未对齐的指针时中止。

答案 3 :(得分:0)

也许你可以通过所有对齐的动作以某种方式编译到SSE。使用movaps进行的未对齐访问是非法的,可能会在其他架构上进行非法的未对齐访问。