|
|
1
10
Linux内核代码在x86上的4K堆栈上运行。因此他们关心。他们用来检查的是他们编写的一个Perl脚本,您可以在最近的内核tarball中找到它作为scripts/checkstack.pl。它运行在objdump的输出上,使用文档在初始注释中。 我想很久以前我就已经在用户空间二进制文件中使用过它了,如果您知道一些Perl编程,那么如果它被破坏了,就很容易修复它。 不管怎样,它基本上是自动查看gcc的输出。内核黑客编写了这样一个工具,这意味着没有静态的方法来处理gcc(或者可能它是最近添加的,但我对此表示怀疑)。 顺便说一句,使用mingw项目和activeperl中的objdump,或者使用cygwin,您应该也能够在Windows以及其他编译器获得的二进制文件中这样做。 |
|
|
2
8
Stackanlyser似乎检查了可执行代码本身以及一些调试信息。 描述的内容 this reply ,这是我要找的,堆栈分析器在我看来是杀伤力太大了。 类似于Ada存在的东西会很好。从GNAT手册中查看本手册页面: 22.2静态堆栈使用分析 使用-fstack用法编译的单元将生成一个额外的文件,指定每个函数使用的最大堆栈量。该文件与扩展名为.su的目标对象文件具有相同的基名称。此文件的每一行由三个字段组成:
第二个字段对应于函数框架的已知部分的大小。 限定符static表示函数帧大小是纯静态的。它通常意味着所有局部变量都有一个静态大小。在这种情况下,第二个字段是对函数堆栈利用率的可靠度量。 限定符dynamic表示函数帧大小不是静态的。它主要发生在一些局部变量具有动态大小的情况下。当这个限定符单独出现时,第二个字段不是函数堆栈分析的可靠度量。当限定为有界时,意味着第二个字段是函数堆栈利用率的可靠最大值。 |
|
|
3
3
我不明白为什么静态代码分析不能给出足够好的数字。 在任何给定函数中查找所有局部变量都很简单,每个变量的大小可以通过C标准(对于内置类型)或通过计算(对于结构和联合等复杂类型)找到。 当然,答案不能保证100%准确,因为编译器可以进行各种优化,如填充、将变量放入寄存器或完全删除不必要的变量。但它给出的任何答案至少都应该是一个很好的估计。 我做了一个快速的谷歌搜索,发现 StackAnalyzer 但我猜其他静态代码分析工具也有类似的功能。 如果你想要一个100%准确的数字,那么你必须查看编译器的输出或者在运行时检查它(就像Ralph在 his reply ) |
|
|
4
1
只有编译器才会真正知道,因为是他把你所有的东西放在一起。您必须查看生成的程序集,并查看序言中保留了多少空间,但这并不能真正解释诸如
|
|
|
5
1
假设您在一个嵌入式平台上,您可能会发现您的工具链在这方面有一个优势。好的商业嵌入式编译器(例如arm/keil编译器)通常会生成堆栈使用情况的报告。 当然,中断和递归通常有点超出了它们的范围,但是如果有人在堆栈的某个地方用一个兆字节的缓冲区犯了一些可怕的错误,它会给你一个粗略的概念。 |
|
|
6
1
不完全是“编译时”,但我会在构建后的步骤中这样做:
这与StackAnalyzer类似,但要简单得多。我认为分析可执行文件或反汇编是获得编译器输出的最简单方法。虽然编译器在内部知道这些事情,但恐怕您无法从中获得(您可能会要求编译器供应商实现该功能,或者如果使用开放源代码编译器,您可以自己做,也可以让别人帮您做)。 要实现这一点,您需要:
这有多容易或困难取决于你的目标平台。(嵌入式)?哪个CPU架构?什么编译器?) 所有这些都可以在x86/win32中完成,但是如果您从未做过类似的事情,并且必须从头开始创建所有这些内容,则可能需要几天时间才能完成,并开始工作。 |
|
|
7
-1
一般来说不是。理论计算机科学中的停顿问题表明,你甚至无法预测一个通用程序是否会在给定的输入上停顿。计算用于程序运行的堆栈通常会更复杂。所以:不,可能在特殊情况下。 假设您有一个递归函数,它的递归级别取决于输入,输入的长度可以是任意的,您已经走运了。 |
|
|
George S. · 是否存在基于元组的控制流语句内部表示? 8 年前 |
|
FlatAssembler · 在x86程序集中计算exp(x) 8 年前 |
|
|
cib · 即时编译和动态编译有什么区别? 8 年前 |
|
|
Artemis · 寄存器与指令之间的差异 8 年前 |
|
|
Sam · 了解go工具编译和链接命令 8 年前 |