gcc - 如何使用 gcc 确定嵌入式系统中的最大堆栈使用量?

标签 gcc embedded static-analysis code-analysis yagarto

我正在为嵌入式系统编写启动代码 - 在跳转到 main() 函数之前加载初始堆栈指针的代码 - 我需要告诉它我的应用程序将使用多少字节的堆栈(或一些更大的、保守的估计)。

我被告知 gcc 编译器现在有一个 -fstack-usage 选项和 -fcallgraph-info 选项,可以以某种方式用于为我静态计算准确的“最大堆栈使用量”。 ("Compile-time stack requirements analysis with GCC",作者:Botcazou、Comar 和 Hainque)。

Nigel Jones 说递归在嵌入式系统中是一个非常糟糕的主意 ("Computing your stack size" 2009),因此我一直小心翼翼地不在这段代码中创建任何相互递归的函数。

此外,我还确保我的中断处理程序在最终从中断返回指令之前不会重新启用中断,因此我不需要担心可重入中断处理程序。

如果没有递归或可重入中断处理程序,应该可以静态确定最大堆栈使用量。 (因此 How to determine maximum stack usage? 的大多数答案都不适用)。 我的理解是,我(或者最好是我的电脑上的一些代码,每次重建可执行文件时都会自动运行)首先找到每个中断处理程序在没有被更高优先级中断中断时的最大堆栈深度,以及最大堆栈深度。 main() 函数未中断时的堆栈深度。 然后我将它们全部加起来以找到总(最坏情况)最大堆栈深度。 (在我的嵌入式系统中)当 main() 后台任务被最低优先级中断打断时处于最大深度,并且当被下一个最低优先级中断打断时,该中断处于最大深度时,就会发生这种情况中断等。

我使用 YAGARTO 和 gcc 4.6.0 来编译 LM3S1968 ARM Cortex-M3 的代码。

那么如何将 -fstack-usage 选项和 -fcallgraph-info 选项与 gcc 一起使用来计算最大堆栈深度?或者是否有更好的方法来确定最大堆栈使用量?

(有关针对 Keil 编译器的几乎相同的问题,请参阅 How to determine maximum stack usage in embedded system?。)

最佳答案

GCC docs :

-fstack-usage

Makes the compiler output stack usage information for the program, on a per-function basis. The filename for the dump is made by appending .su to the auxname. auxname is generated from the name of the output file, if explicitly specified and it is not an executable, otherwise it is the basename of the source file. An entry is made up of three fields:

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

The qualifier static means that the function manipulates the stack statically: a fixed number of bytes are allocated for the frame on function entry and released on function exit; no stack adjustments are otherwise made in the function. The second field is this fixed number of bytes.

The qualifier dynamic means that the function manipulates the stack dynamically: in addition to the static allocation described above, stack adjustments are made in the body of the function, for example to push/pop arguments around function calls. If the qualifier bounded is also present, the amount of these adjustments is bounded at compile-time and the second field is an upper bound of the total amount of stack used by the function. If it is not present, the amount of these adjustments is not bounded at compile-time and the second field only represents the bounded part.

我找不到任何对 -fcallgraph-info 的引用

您可以通过 -fstack-usage 和 -fdump-tree-optimized 创建所需的信息

对于 -fdump-tree-optimized 中的每个叶子,从 -fstack-usage 获取其父节点并对它们的堆栈大小数字求和(请记住,该数字适用于任何具有“动态”但非“有界”的函数),找到这些值中的最大值,这应该是您的最大堆栈使用量。

关于gcc - 如何使用 gcc 确定嵌入式系统中的最大堆栈使用量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6387614/

相关文章:

c++ - 在 VC++ 中步入 MACRO

c++ - 如何 Qt - Qml 调试和/或分析?

embedded - u-boot - 选择正确的 linux 镜像

c - 引擎盖下的 volatile

c# - ASP.NET/C# 等同于用于 SQL 注入(inject)的 Microsoft 源代码分析器 (MSSCASI_ASP)?

c++ - 使用 LLVM 检测 C/C++ 代码

code-analysis - 静态代码分析方法

c - “noreturn”函数确实返回

c - gcc 如何计算结构所需的空间?

c - 在构建期间仅在标题中显示 #pragma 消息一次