【发布时间】:2013-03-22 09:48:16
【问题描述】:
在不使用递归的 C 程序中,理论上应该可以计算出调用给定函数以及它调用的任何函数所需的最大/最坏情况堆栈大小。是否有任何免费的开源工具可以做到这一点,无论是来自源代码还是编译的 ELF 文件?
或者,有没有办法从 ELF 文件中提取函数的堆栈帧大小,以便我可以尝试手动解决?
我正在使用 MSPGCC 3.2.3 为 MSP430 进行编译(我知道它是旧版本,但在这种情况下我必须使用它)。要分配的堆栈空间是在源代码中设置的,并且应该尽可能小,以便剩余的内存可以用于其他事情。我已经读到您需要考虑中断使用的堆栈空间,但我正在使用的系统已经考虑到这一点 - 我正在尝试计算在此之上添加多少额外空间。另外,我读过函数指针使这变得困难。在此处使用函数指针的少数地方,我知道它们可以调用哪些函数,因此如果已知被调用函数和调用函数所需的堆栈空间,则可以手动考虑这些情况。
静态分析似乎是比运行时堆栈绘制更强大的选项,但如果没有好的静态方法可以在运行时解决它是一个选项。
编辑:
我找到了 GCC 的 -fstack-usage 标志,它在编译时保存了每个函数的帧大小。不幸的是,MSPGCC 不支持它。但它对于尝试在不同平台上做类似事情的人来说可能很有用。
【问题讨论】:
-
这真的是解决您问题的方法吗?我总是对堆栈相当慷慨,并用堆栈金丝雀保护它以确保它完好无损。我认为这种方法的主要问题是它可能会在以后引起麻烦。例如,当您需要使用 24 位 PC 而不是 16 位(现在只是一般的 8 位体验)来获得更大的程序内存时,或者您只需要一些额外的功能,最好通过一些额外的调用层来实现。然后一个精确设置的堆栈可能真的会回到你身上。当然,如果您要挤出最后一点,那好吧,但我认为这确实应该是最后一点。
-
“是否有任何免费的开源工具可以做到这一点”。有一个免费版本的(非开源)IAR IDE(30 天或 4K 代码限制),其中链接器列表选项生成应用程序的堆栈使用情况。即使您使用的是 GCC,为了获取堆栈大小(每个函数的总和)、代码大小(每个函数的总和)以及内存位置、变量地址和大小等其他详细信息,您也可以使用 IAR嵌入式工作台。