在不使用递归的C程序中,理论上应该可以计算出调用给定函数所需的最大/最坏情况堆栈大小以及它调用的任何东西。是否有任何免费的开源工具可以做到这一点,或者从源代码或编译的ELF文件?
或者,是否有一种方法从ELF文件中提取函数的堆栈帧大小,以便我可以尝试手动计算它?
我正在使用MSPGCC3.2.3为MSP430编译(我知道它是一个旧版本,但在本例中我必须使用它)。要分配的堆栈空间在源代码中设置,并且应该尽可能小,以便剩余的内存可以用于其他事情。我读到过,您需要考虑中断所使用的堆栈空间,但是我使用的系统已经考虑到了这一点--我正在试图在此基础上增加多少额外的空间。另外,我还读过函数指针,这使得这很困难。在这里使用函数指针的少数地方,我知道它们可以调用哪些函数,因此如果知道调用函数和调用函数所需的堆栈空间,可以手动考虑这些情况。
静态分析似乎是一个比运行时堆栈绘制更健壮的选项,但是在运行时处理它是一个选项,如果没有好的静态方法来实现它。
编辑:
我找到GCC的-fstack-usage标志,它在编译时保存每个函数的帧大小。不幸的是,MSPGCC不支持它。但对于任何试图在不同平台上做类似事情的人来说,这可能是有用的。
发布于 2013-07-09 03:04:45
虽然静态分析是确定最大堆栈使用量的最佳方法,但您可能不得不求助于一种实验方法。此方法不能保证绝对最大,但可以为您提供堆栈使用的一个非常好的想法。
您可以检查链接器脚本以获得__STACK_END和__STACK_SIZE的位置。您可以使用它们来填充堆栈空间,以便于识别的模式,如0xDEAD或0xAA 55。通过测试运行您的代码,以确保尽可能多地生成中断。
测试之后,您可以检查堆栈空间,以查看覆盖了多少堆栈。
发布于 2013-04-01 10:43:07
有趣的问题。
我希望这些信息在调试生成中包含的调试数据中是静态可用的。
我简要地看了一下矮人标准,它确实为名为DW_AT_frame_base和DW_AT_static_link的函数指定了两个属性,它们可以用来“计算子例程的相关实例的框架基,该子例程直接包围子例程或入口点”。
发布于 2013-04-01 13:46:38
我认为唯一要去的是静态分析。您需要考虑所有非静态局部变量的空间,这些变量将主要是指针,但是无论如何,您需要为调用方内当前运行的地址预留空间,因为它将由编译器存储在堆栈上,以便函数返回后控件可以返回给调用方,而且您还需要为所有函数参数留出空间。基于此,如果您有一个工具能够计算所有参数、自动变量并计算它们的大小,那么您应该能够计算出所需的最小堆栈帧大小。请注意,编译器还可以尝试对齐特定体系结构的堆栈上的值,这样可以使堆栈空间需求比您预期的要大一些。
https://stackoverflow.com/questions/15741429
复制相似问题