有没有办法知道和输出的堆大小需要通过一个函数,在汇编时在C?这里是我想知道:

让我们采取一些功能:

void foo(int a) {
    char c[5];
    char * s;
    //do something
    return;
}

当编制这一功能的,我想知道有多少叠空间,它将消耗when它被称为。这可能是有用的检测的在栈宣言》的结构隐藏着一个很大的缓冲区。

我要寻找的东西,将打印这样的事情:

文件foo。c:function foo堆的使用 n 字节

是否有办法不去看产生的大会知道?或限制可设定用于编译器?

更新:我不试图避免运行时堆溢出对于给定的过程中,我在寻找一种方式找到之前的运行时,如果一个功能堆使用情况,以确定通过编译器,是可以作为一个输出的编纂过程。

让我们把它另一种方法:是否有可能知道的尺寸大小的所有对象,当地的一个功能?我猜编译器化不会成为我的朋友,因为一些变量将消失,而是一个卓越的限制。

有帮助吗?

解决方案

Linux内核代码在x86上的4K堆栈上运行。因此他们关心。他们用来检查它的是他们编写的perl脚本,你可以在最近的内核tarball中找到script / checkstack.pl(2.6.25已经得到它)。它运行在objdump的输出上,使用文档在初始注释中。

我认为我很久以前就已经将它用于用户空间二进制文件了,如果你知道一些perl编程,如果它被破坏就很容易解决。

无论如何,它基本上做的是自动查看GCC的输出。内核黑客编写这样一个工具的事实意味着没有静态的方法来使用GCC(或者可能是最近添加的,但我对此表示怀疑)。

顺便说一下,使用来自mingw项目和ActivePerl的objdump,或者使用Cygwin,你也应该能够在Windows上以及使用其他编译器获得的二进制文件上做到这一点。

其他提示

StackAnlyser似乎在检查可执行代码本身以及一些调试信息。 我正在寻找的是此回复所描述的内容,堆栈分析器对我来说太过分了。

与ADA相似的东西会很好。从gnat手册中查看本手册页:

22.2静态堆栈使用分析

使用-fstack-usage编译的单元将生成一个额外的文件,该文件指定每个函数的最大堆栈使用量。该文件与具有.su扩展名的目标对象文件具有相同的基本名称。该文件的每一行由三个字段组成:

* The name of the function.
* A number of bytes.
* One or more qualifiers: static, dynamic, bounded. 

第二个字段对应于功能框架的已知部分的大小。

限定符static意味着函数框架大小是纯静态的。它通常意味着所有局部变量都具有静态大小。在这种情况下,第二个字段是功能堆栈利用率的可靠度量。

限定符动态意味着函数框架大小不是静态的。它主要发生在某些局部变量具有动态大小时。当此限定符单独出现时,第二个字段不是功能堆栈分析的可靠度量。当它有界限限定时,意味着第二个字段是功能堆栈利用率的可靠最大值。

我不明白为什么静态代码分析无法为此提供足够好的数据。

在任何给定函数中找到所有局部变量是微不足道的,并且每个变量的大小可以通过C标准(对于内置类型)或通过计算(对于结构和联合等复杂类型)找到。

当然,答案不能保证100%准确,因为编译器可以进行各种优化,如填充,将变量放入寄存器或完全删除不必要的变量。但它给出的任何答案至少应该是一个很好的估计。

我做了一个快速的谷歌搜索,找到了 StackAnalyzer ,但我的猜测是其他静态代码分析工具具有类似的功能。

如果你想要100%准确的数字,那么你必须查看编译器的输出或在运行时检查它(如Ralph在他的回复

只有编译器真的知道,因为它是将你所有东西放在一起的人。您必须查看生成的程序集并查看前导码中保留了多少空间,但这并不能解决像 alloca 这样在运行时执行其操作的内容。

假设您使用的是嵌入式平台,您可能会发现您的工具链可以解决这个问题。良好的商业嵌入式编译器(例如Arm / Keil编译器)通常会生成堆栈使用情况的报告。

当然,中断和递归通常有点超出它们的范围,但是如果有人在某个地方使用多兆字节缓冲区进行了一些可怕的搞砸,它会给你一个粗略的想法。

不完全是"编译时间",但是我会做这个作为后建立的步骤:

  • 让我们连接创建一个地图文件给你
  • 每个功能在地图文件的读取相应部分的可执行,并分析功能的序幕。

这是类似于什么StackAnalyzer,但简单得多。我想分析或可执行的拆卸是最简单的方式可以获得编译器的输出。同时,编译器知道那些东西在内部,我是怕你会不能够得到它从它的(你可能会要求编译器供应商实施的功能,或者如果使用开放源码编译器,你可以自己做还是让别人为你做).

要实现这一点,你需要:

  • 能够分析文件的地图
  • 理解的格式的可执行
  • 知道什么是功能的序言可能看起来象,能够"解"它

如何简单或困难的,这将取决于你的目标的平台。(嵌入式?这CPU架构?什么编译器?)

所有这肯定是可以做到在x86/Win32,但是如果你从来没有像这样的东西,并已创建这一切从头开始,它可能需要几天前你都做了,有一些工作。

不一般。理论计算机科学中的暂停问题表明,你甚至无法预测一般程序是否会在给定输入上停止。计算用于程序运行的堆栈通常会更复杂。所以不行。也许在特殊情况下。

假设您有一个递归函数,其递归级别取决于输入,该输入可以是任意长度,并且您已经不幸了。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top