【问题标题】:detecting stack overwrite error检测堆栈覆盖错误
【发布时间】:2012-06-18 11:47:29
【问题描述】:

我正在为 Cortex-M3 嵌入式微控制器 (Atmel SAM3S) 开发软件 我使用 IAR EWARM IDE 和编译器。 我怀疑由于某种原因我有缓冲区溢出或内存泄漏,导致堆栈损坏,因为我突然发现自己卡在了我的代码空间之外。

我问这个问题的原因是,很难找出究竟是什么导致了这个混乱,我想知道当你想找出问题的原因时你使用了哪些技术。

您是否在使用内存调试器、在线跟踪调试硬件等。

【问题讨论】:

    标签: c debugging arm cortex-m3


    【解决方案1】:

    您应该尝试使用金丝雀值。基本上就是这样——假设你有一些struct

    struct foo {
        unsigned long bar;
        void * baz;
    };
    

    修改它,使它看起来像这样:

    struct foo {
        unsigned long canary1;
        unsigned long bar;
        void * baz;
        unsigned long canary2;
    };
    

    在初始化struct 时,将一些任意值放入canary1canary2。每当您对 struct 进行一些操作时,请检查值是否保持不变。这样,如果您有缓冲区溢出或堆栈粉碎,您将检测到它。您可以使用自动变量执行相同的内部函数:

    int foo(int bar) {
          unsigned long canary1 = 0xDEADBABE;
          char baz[20];
          unsigned long canary2 = 0xBAD0C0DE;
          ...
    }
    

    等等。不要忘记在return 之前检查这些值是否保持不变。此外,如果您可以让代码始终跳转到同一位置,请尝试将一些代码放在那里(或断点)并获取堆栈跟踪。

    GCC 知道如何自己添加这些金丝雀值,但我不知道您的编译器是否可以这样做。但您仍然可以手动完成。

    【讨论】:

    • 我们做类似的事情,我们将在数据和 bss 的末尾放置一个“主”金丝雀值(我们的堆栈从末尾向后增长)。我们在启动时初始化该值,并在堆栈溢出或随机写入的情况下不断检查它。
    【解决方案2】:

    程序计数器是一个寄存器,因此它不能被“覆盖”。正如您所说,可能发生的情况是堆栈被覆盖,然后您执行返回指令,该指令从堆栈中读取无效的返回地址,从而导致跳转到 la-la-land。

    我最喜欢的调试方法是打印出来,当然这在嵌入式目标上可能很困难。第二好的方法是逐步检查可疑程序。

    您还应该调查已知会导致跳转的事物,例如中断服务例程。

    【讨论】:

      【解决方案3】:

      我在 STM32 上使用 IAR EWARM 时遇到了类似的问题。内存转储、反汇编、金丝雀,都一无所获。最后回滚到 EWARM 的早期版本,问题就消失了。我向 IAR 支持发送了一条消息,但从未收到回复。抱歉,我不记得这是哪个版本的 EWARM。这是几个项目之前的事情。

      我会保持一个内存窗口打开并首先尝试金丝雀测试。如果它仍然随机跳出代码空间,请尝试安装旧版本的 EWARM。

      【讨论】:

        【解决方案4】:

        我可以补充一点,对于 ARM 芯片,有可能某处存在 BL 而不是 BX 或 BLX,从而导致芯片进入错误的 Thumb/ARM 模式。不像后来的芯片那么常见,但仍然......

        当我发现无处跳转时,我会寻找错误的函数指针表、任何中断向量表的覆盖,以及是最容易测试的堆栈溢出。将已知字节值放入您的堆栈区域,当崩溃发生时,查看调试器还剩下多少堆栈。如果没有,那就去吧。

        我还会按照标准查看过去 X 天的内容发生了什么变化,以尝试找出任何问题。最后,只需从代码中 printf 尝试缩小错误跳转发生的位置。如果您可以将其归结为一两个函数,您可以跟踪汇编程序并很快查看它是编译器问题、内存问题还是中断问题。祝你好运!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-04-06
          • 1970-01-01
          • 2017-11-01
          • 2012-04-02
          • 2021-12-09
          • 2018-09-28
          • 2011-12-05
          相关资源
          最近更新 更多