是否有一种编程方法来检查堆栈损坏[英] Is there a programmatic way to check stack corruption

本文是小编为大家收集整理的关于是否有一种编程方法来检查堆栈损坏的处理方法,想解了是否有一种编程方法来检查堆栈损坏的问题怎么解决?是否有一种编程方法来检查堆栈损坏问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我正在使用多线程嵌入式应用程序.每个线程都是根据其功能分配的堆栈尺寸.最近,我们发现其中一个线程通过定义一系列局部变量而不是堆栈大小来破坏堆栈.操作系统是uitron.

我的解决方案, 我注册了一个计时器10 ms,此计时器将检查堆栈损坏.

堆叠损坏检查方法, 1.用一些唯一的模式初始化堆栈内存(我使用0x5A5A5A5A) 2.检查堆栈内存的顶部是否仍然是0x5A5A5A5A

我的问题,

是否有更好的方法检查这种类型的损坏

忘了添加,立即添加:OS:ITRON,处理器:ARM9.编译器:不是GCC(由处理器供应商提供的ARM9特定于ARM9)...并且没有内置支持堆栈检查...

推荐答案

最近在嵌入式平台上工作时,我看上去很高而低点来做到这一点(这是在ARM7上).

建议的解决方案是您已经提出的:使用已知模式初始化堆栈,并确保从函数返回后存在模式.我认为同样的事情"必须有更好的方法",而"没有人自动化这一点".两个问题的答案都是"否",就像您所做的那样,我必须在尝试寻找腐败发生的地方.

我还为data_abort的"滚动"异常向量.这是您可以使用JTAG调试器来做的事情,当这些中止矢量发生时,请打破,然后研究堆栈.如果您只有1或2个断点(这似乎是ARM JTAG调试的规范),这可能很有用.

其他推荐答案

ARM9具有JTAG/ETM调试支持.您应该能够设置涵盖涵盖的数据访问观察点,例如64个字节在堆栈顶部附近,然后会触发数据中止,您可以在程序中或外部捕获.

(我与之合作的硬件仅支持2个读/写观察点,不确定这是片上的东西还是周围的第三方调试套件的限制.)

在 - 如何与JTAG功能接口的描述,建议您阅读处理器的技术参考手册 - 我可以保证第9章(" debug Support")在 arm946e-s r1p1 trm .

在您挖掘所有这些东西之前(除非您只是为了娱乐/教育而做),请仔细检查您所使用的硬件和软件已经无法为您管理断点/观察点.在我们使用的调试软件中很难找到"观察点"的概念 - 这是一个标记为"硬件"的标签.

.


另一种选择:您的编译器可以支持命令行选项,以在函数的条目和退出点添加函数调用(某种" void enterfunc(const char * callfunc)"和" void exitfunc(const chall * callfunc) )",用于功能成本分析,更准确的堆栈跟踪或类似.然后,您可以编写这些功能以检查您的堆栈金丝雀值.

(顺便说一句,在我们的情况下,我们实际上忽略了传递的函数名称(我希望我可以让链接器剥离它们),然后只使用处理器的链接寄存器(LR)值记录我们来自的位置.我们将其用于获取准确的呼叫跟踪以及分析信息;此时检查堆栈金丝雀也很微不足道!)

问题当然是在我们的实验中,调用这些功能会更改寄存器和堆叠功能的堆栈配置文件,但要点一点.绩效的影响更糟,无论绩效含义在哪里,都有行为改变程序的机会,这可能意味着您,例如避免触发您在...

之前可能拥有的深层回归案例

非常晚更新:这些天,如果您有基于clang+llvm的管道,则可以使用地址消毒剂(ASAN)捕获其中一些.请注意编译器中的类似功能! (值得了解 ubsan "> ubsan 和其他卫生室也是如此. )

其他推荐答案

您正在使用什么编译器?我猜是一个特定的操作系统.如果您正在使用GCC,则可以使用 stack-smashing"> stack-smashing"> stack-smashing ">保护者.这可能是您的生产系统的解决方案,可以防止问题,还可以使您在开发中检测到它.

要有效检查堆栈损坏,您需要检查可用的堆栈空间,在通话前将警卫放在堆栈参数的两侧,进行呼叫,然后在呼叫的返回中检查警卫.这种更改通常需要对编译器生成的代码进行修改.

本文地址:https://www.itbaoku.cn/post/359214.html