【问题标题】:Debugging memory issues ARM7调试内存问题ARM7
【发布时间】:2018-01-26 15:07:03
【问题描述】:

我在尝试调试看似非常奇怪的行为时遇到了一些问题。例如,我们有:

static const char* LOG_FORMAT = "0x%02x,%.5f,";

并且指针没有明显的原因发生变化。有时是垃圾,有时是代码中其他地方定义的其他常量字符串(或部分)。我们偶尔也会看到代码跳转到不应该运行的不同部分(状态变量似乎在没有被要求的情况下更改)。有 2 或 3 种常见的故障模式,它们似乎是随机发生的。这是一个相对较大的代码库,添加或删除某些部分会改变故障行为(或完全删除它),即使这些部分从未被引用。

目前最好的理论是,这是一个与内存相关的问题,因为我们已经用细齿梳了解了最近的所有变化,插入代码段以移动事物的简单行为似乎发生了变化或删除该行为。

调试此问题或类似问题的最佳方法是什么?发现调试器有时很有用,而在其他时候却没有用(但这可能是用户错误)。

补充说明。 ARM7,使用 Keil µVision 4 和 armcc v4.1 编译器。

【问题讨论】:

  • 我使用 ARM7 已经有一段时间了,但我相信它有几个可用的硬件断点。设置一个以观察对LOG_FORMAT 指针变量的写入,然后查看修改它的内容。
  • 对我来说肯定听起来像 UB,但你可能已经知道了。在不同但相同的硬件上出现同样奇怪的行为?
  • 不是直接指向字符串,而是分配一些内存给 LOG_FORMAT,然后将字符串复制到 LOG_FORMAT。
  • 您正在使用什么 c 库和/或这是在操作系统上吗?
  • 如此广泛的损坏是堆栈溢出的典型(但不限于);您是否验证了足够的堆栈分配?您的问题只能是非法的建议或意见,不能就目前的情况得到明确的回答;当然教你使用调试器可能太宽泛了,但你至少可以检查堆栈内存(预先填充它)和 SP 寄存器值。

标签: c embedded arm7 armcc


【解决方案1】:

这意味着您在程序中的某处存在指针错误/内存损坏......这可能是由很多不同的事情引起的。

发现这一点的最简单方法是运行程序直到 main 启动,然后向变量添加“写入”断点。这应该直接指出有问题的代码。

一个可能的原因是堆栈溢出,堆栈被放置在错误的内存位置,因此在溢出时它开始覆盖.data.bss。见this article

您可以通过在启动时将所有堆栈内存设置为已知值(例如 0xAA)来调试堆栈溢出,让程序运行一段时间,尝试将其暴露给尽可能多的用例,然后打破并检查堆栈的内存,看看知道值仍然保留到多深。如果这接近堆栈的末尾,那么您很可能发生堆栈溢出。

【讨论】:

    【解决方案2】:

    这看起来像是堆栈未对齐问题。您的堆栈可能在单字(四字节)边界而不是双字(八字节)边界上对齐。

    这就是为什么删除和添加不相关的部分会导致不同的行为。堆栈会从对齐变为未对齐,具体取决于它之前的数据量。

    损坏的格式说明符是另一个线索。在调用可变参数函数之前,未对齐的堆栈通常不会导致任何问题——尤其是传递一个需要双字对齐的值的函数。

    要调试它,您应该在调用printf(或使用格式说明符的任何函数)处设置断点并查看堆栈指针。如果 SP 没有在 8 字节边界上对齐,那么您就发现了问题。

    【讨论】:

      猜你喜欢
      • 2010-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-10
      • 1970-01-01
      • 2021-12-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多