如何捕获未对齐的内存访问?

Posted

技术标签:

【中文标题】如何捕获未对齐的内存访问?【英文标题】:How to trap unaligned memory access? 【发布时间】:2013-05-09 00:31:49 【问题描述】:

我正在开发一个实现一些流密码算法的宠物开源项目,但我遇到了一个只有在 ARM 处理器上运行时才会触发的错误。我什至尝试在 qemu 下在 x86 中运行 ARM 二进制文件,但那里没有触发该错误。

该错误的具体机制仍然难以捉摸,但我最好的办法是相信它是由我的程序中未对齐的内存访问尝试引起的,这是由 qemu 实现的,但在我的开发中被真正的 ARM 处理器默默地忽略了板。

所以,由于这个问题很难诊断,我想知道是否有任何工具可以用来捕获我正在运行的程序进行的未对齐内存访问,以便我可以准确地看到问题发生了。

如果进程违反内存对齐限制,我还可以在我的 ARM 开发板上使用某种方式启用某些信号(可能是 SIGBUS?),例如我们在访问未映射的内存地址时得到 SIGSEGV。它运行的是 Linux 2.6.32。

【问题讨论】:

这至少与您使用的 ARM 架构有关。断点是 ARMv6 afaik。 【参考方案1】:

Linux 可以为您进行修复或警告访问。

您可以在 /proc/cpu/alignment 中启用该行为,有关不同值的说明,请参阅 http://www.mjmwired.net/kernel/Documentation/arm/mem_alignment。

0 - Do nothing (default behavior)
1 - Warning in kernel-log with PC and Memory-Address printed.
2 - Fixup error
3 - Warn and Fixup
4 - Send a SIGBUS to the process
5 - Send SIGBUS and output Warning

【讨论】:

对不起,我们是竞争条件。如果你想从我的回答中获取信息,我会删除它。 我没问题,让 OP 决定。 ;) 我只是来帮忙的。 我在 x86 或 powerpc 中看不到 /proc/cpu/alignment 选项。在 x86 或 powerpc 的情况下,我们如何找出应用程序进行的未对齐访问? IIRC 在 x86 上有性能计数器,可以计算未对齐的访问。你需要一个分析器来阅读它们。不确定powerpc。在 ARMv5 上,未对齐的访问会生成内核必须处理的异常。其他架构可以自然地处理未对齐的访问,而不会受到内核的干扰。 我相信这个答案会更好,因为它列出了我可以在 Linux 内核中设置的所有可能的行为来处理这个问题。就我而言,由于我在调试程序,所以我使用了4 - Send a SIGBUS to the process,GDB 为我提供了导致问题的准确行。【参考方案2】:

ARM Linux 维护着一个对齐处理程序异常列表,

$ cat /proc/cpu/alignment 
User:           0
System:         0
Skipped:        0
Half:           0
Word:           0
DWord:          0
Multi:          0
User faults:    0 (ignored)

只有 procfs 才有效,但很难想象没有 procfs 的系统。处理此问题的具体代码在alignment.c 中。您可以使用 echo 3 > /proc/cpu/alignment 让 Linux fixup 指令并提供一些 dmesg 输出。通常,通过仿真处理未对齐的访问是非常低效的。最好更正代码。带有调试器的 signal 选项应该提供一些关于异常来源的线索。

阅读manual。 ;-)

【讨论】:

尽管我将 /proc/cpu/alignment 设置为 5,但在 dmesg 中没有看到任何消息。理想情况下,它应该发送信号并生成警告。我错过了什么吗? @linuxfreak 您应该执行cat /proc/cpu/alignment 并查看 User faults 行的内容(应该是 5 (signal+warn)。另外,您的内核可能已修改。验证 User 行是否在递增。Line 915 具有 printk,它是未修饰的,因此大多数正常的日志级别应该显示它。如果 User 行没有增加,那么你可能有一个 CPU 正在执行未对齐的访问。

以上是关于如何捕获未对齐的内存访问?的主要内容,如果未能解决你的问题,请参考以下文章

内存对齐以及如何关闭内存对齐

内存对齐问题

c/c++内存对齐详解

内存对齐

内存地址对齐

内存对齐与自定义类型