如何估算含嵌套调用的函数栈用量?GCC工具相关咨询
针对Cortex-M项目栈用量与调用图问题的解决方案
1. 可靠生成代码调用图的方法
GCC自带方案
- 使用
-fdump-analyzer-callgraph:编译时添加该选项,例如:
会生成后缀为arm-none-eabi-gcc -c -O0 -fdump-analyzer-callgraph your_source.c.c.analyzer的文件,提取其中digraph callgraph块保存为.dot文件,再用Graphviz的dot工具转换为可视化格式或文本:
注意:若需保留dot -Tpng callgraph.dot -o callgraph.png # 生成图片 dot -Ttext callgraph.dot # 查看文本调用关系static inline函数,需搭配-O0或-fno-inline避免内联优化。 - 使用
-fdump-tree-ch:生成包含调用层次信息的.c.tree文件,适合脚本自动化解析调用链,命令示例:arm-none-eabi-gcc -c -fdump-tree-ch your_source.c
第三方工具方案
- Clang + llvm-callgraph:先用
bear make生成编译数据库,再通过llvm-callgraph生成调用图,对static、static inline函数的支持更友好,命令示例:bear make # 生成compile_commands.json llvm-callgraph compile_commands.json -o callgraph.dot - CodeViz:专门针对C/C++的调用图工具,支持处理同名
static函数,安装后通过cgif命令生成,需配置头文件路径与预定义宏:cgif -I./inc -DSTM32F4XX your_source.c
2. GCC相关调用图选项详解
-fdump-analyzer-callgraph
- 核心用途:生成Graphviz格式的调用图数据,直接提取文件中的
digraph块即可使用。 - 注意事项:优化级别会影响调用图完整性,若需分析未内联的函数调用,需禁用内联优化。
-fdump-tree系列
- 常用子选项:
-fdump-tree-cfg:生成控制流图,包含函数内部的调用节点;-fdump-tree-ch:输出函数调用层次结构,便于脚本提取调用链;-fdump-tree-all:输出所有树相关分析数据,信息最全面但体积较大。
- 用法:编译时直接添加对应子选项,生成的
.tree文件可通过正则或脚本解析调用关系。
-fcallgraph-info
- 该选项为PGO(profile-guided optimization)服务,用于收集调用信息与栈使用数据,格式为
-fcallgraph-info=<type>,可选su(栈使用)、ci(调用信息)等。 - 局限性:输出为PGO工具专用格式,不适合手动分析调用图,一般不单独用于生成调用关系。
3. 跨嵌套调用的栈用量计算方案
GCC+自定义脚本
- 用
-fstack-usage生成每个函数的栈用量文件(.su),示例命令:arm-none-eabi-gcc -c -fstack-usage your_source.c - 用
-fdump-analyzer-callgraph生成调用图; - 编写脚本(如Python)解析调用图与
.su文件,递归计算每个函数调用链的最大栈用量(栈为累加模式,取调用树中路径的最大值)。
专用工具stackusage
- 专门分析GCC
.su文件与调用图的开源工具,可自动计算函数的最大嵌套栈用量,只需输入.su文件路径与调用图数据即可输出结果。
Clang静态分析
- 使用Clang的静态分析工具,搭配栈相关检查器,例如:
不仅能检测栈溢出风险,还能结合clang --analyze -analyzer-checker=core.StackAddressEscape your_source.c-fstack-usage输出,全面分析嵌套调用的栈使用情况。
Cortex-M专属方案
- 结合链接脚本定义栈区域,用
arm-none-eabi-size查看全局栈分配,再搭配上述调用图与栈用量分析,可得到单个函数的精确嵌套栈用量。
内容的提问来源于stack exchange,提问作者mastupristi
相关产品推荐
相关产品推荐

