C语言 调试内存问题 ARM7



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

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

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

目前最好的理论是,这是一个与内存相关的问题,因为我们已经用细齿梳子检查了所有最近的更改,并且插入代码段以移动内容的简单行为似乎可以更改或删除行为。

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

进一步说明。ARM7,使用 Keil μVision 4 和 armcc v4.1 编译器。

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

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

一个可能的原因是堆栈溢出,其中堆栈放置在错误的内存位置,因此在溢出时它开始覆盖.data.bss。请参阅此文章。

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

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

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

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

若要调试此问题,应在调用printf(或格式说明符用于的任何函数(处设置断点,并查看堆栈指针。如果 SP 未在 8 字节边界上对齐,则您发现了问题。

相关内容

  • 没有找到相关文章

最新更新