c - 有没有一种程序化的方法来检查堆栈损坏

标签 c multithreading embedded stack

我正在使用多线程嵌入式应用程序。每个线程都根据其功能分配堆栈大小。最近我们发现其中一个线程通过定义一个大于堆栈大小的局部变量数组破坏了堆栈。操作系统是uItron。

我的解决方案, 我注册了一个 10 毫秒的计时器,这个计时器将检查堆栈是否损坏。

堆栈损坏检查方法, 1. 用一些独特的模式初始化堆栈内存(我使用 0x5A5A5A5A) 2.从时间上看栈顶内存是否还是0x5A5A5A5A

我的问题,

有没有更好的方法来检查这种类型的损坏

忘记补充了,现在补充:操作系统:Itron,处理器:ARM9。编译器:不是 GCC(处理器供应商提供的 ARM9 特定)...并且没有内置的堆栈检查支持...

最佳答案

ARM9 具有片上 JTAG/ETM 调试支持;您应该能够设置一个数据访问观察点,例如靠近堆栈顶部的 64 个字节,这将触发数据中止,您可以在程序中或外部捕获它。

(我使用的硬件只支持 2 个读/写观察点,不确定这是片上东西还是周围第三方调试工具包的限制。)

This document ,这是关于如何与 JTAG 功能交互的极低级别的描述,建议您阅读处理器的 Technical Reference Manual。 -- 我可以保证在第 9 章(“调试支持”)中有大量关于 ARM946E-S r1p1 TRM 的高级信息。 .

在深入了解所有这些内容之前(除非您只是为了娱乐/教育),请仔细检查您正在使用的硬件和软件是否已经为您管理断点/观察点。在我们使用的调试软件中很难找到“观察点”的概念——它是添加断点对话框中标记为“硬件”的选项卡。


另一种选择:您的编译器可能支持命令行选项以在函数的入口点和导出点添加函数调用(某种“void enterFunc(const char * callingFunc)”和“void exitFunc(const char * callingFunc) )"),用于函数成本分析、更准确的堆栈跟踪等。然后您可以编写这些函数来检查您的堆栈金丝雀值。

(顺便说一句,在我们的例子中,我们实际上忽略了传入的函数名称(我希望我能让链接器去掉这些),只使用处理器的链接寄存器 (LR) 值来记录我们来自哪里。我们用它来获取准确的调用跟踪和分析信息;此时检查堆栈金丝雀也很简单!)

当然,问题是,调用这些函数会稍微改变函数的寄存器和堆栈配置文件……在我们的实验中,变化不大,但有一点。性能影响更糟,只要有性能影响,程序中就有可能发生行为改变,这可能意味着你,例如。避免触发您之前可能遇到的深度递归情况...


非常晚的更新:现在,如果你有一个基于 clang+LLVM 的管道,你也许可以使用 Address Sanitizer (ASAN)捕获其中的一些。请注意编译器中的类似功能! (值得了解 UBSAN 和其他 sanitizer 。)

关于c - 有没有一种程序化的方法来检查堆栈损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1424635/

相关文章:

c - 当我访问结构的成员时发生段错误

c# Thread不会将Row添加到DataGridView CrossThreadError

java - ArrayBlockingQueue : should use to create Pool?

java - setContextClassLoader 在并发调用时速度急剧下降

c - 启用 const 数组的部分

embedded - 寻找二进制图像布局工具

embedded - 裸机微 Controller 应用程序中是否需要 GCC 的 .fini 部分?

c - 为什么当我试图获得 60 时 FPS 显示 30?

转换c指针类型

arrays - Kattis - Odd Man Out - 段错误