如何从 c 代码中提取所有库函数的堆栈大小?

Posted

技术标签:

【中文标题】如何从 c 代码中提取所有库函数的堆栈大小?【英文标题】:How to extract stack size of all library functions from c code? 【发布时间】:2015-07-14 16:09:24 【问题描述】:

我很少有像 fft、dijkstra 这样的基准测试。我想收集所有库函数和用户定义函数的堆栈大小。 C 代码也可用。

我在硬件中管理缓存,所以我需要每个小函数的确切堆栈大小,变量。

【问题讨论】:

编辑你的问题改进它,并解释你问的原因和动机。 @BasileStarynkevitch 我在硬件中管理缓存,所以我需要每个小函数、变量和常量的确切堆栈大小。但目前功能还可以。 在哪个目标处理器上?您是否正在将 GCC 移植到一些新的架构?你是如何管理缓存的? 【参考方案1】:

如果使用最近的GCC 编译,您可以将-fstack-usage 标志传递给gcc(除了优化标志,如果有的话):

根据每个函数使编译器输出程序的堆栈使用信息。转储的文件名是通过将 .su 附加到 auxname 来创建的。 auxname 从输出文件的名称生成,如果明确指定并且它不是可执行文件,否则它是源文件的基本名称。一个条目由三个字段组成:

函数的名称。 字节数。 一个或多个限定符:staticdynamicbounded

限定符static 表示函数静态地操作堆栈:在函数进入时为帧分配固定数量的字节,并在函数退出时释放;没有在函数中进行堆栈调整。第二个字段是这个固定的字节数。

限定符dynamic 表示该函数动态地操作堆栈:除了上面描述的静态分配之外,堆栈调整是在函数体中进行的,例如在函数调用周围推送/弹出参数。如果限定符 bounded 也存在,则这些调整的数量在编译时是有界的,第二个字段是函数使用的堆栈总量的上限。如果不存在,则这些调整的数量在编译时是没有界的,第二个字段只代表有界的部分。

您还可以传递-Wstack-usage=len warning flag,其中:

如果函数的堆栈使用量可能大于 len 个字节,则发出警告。确定堆栈使用情况的计算是保守的。通过alloca、可变长度数组或相关构造分配的任何空间都由编译器在确定是否发出警告时包含在内。

您可以考虑编写您的 GCC plugin 来提取最近 GCC 编译的函数的堆栈大小(例如 2020 年 10 月的 GCC 10),并且由于 GCC 是 free software,您可以改进它。

当然,如果您想要库的相同信息,您应该从它们的源代码重新编译它们。

顺便说一句,某些函数或某些函数调用出现的堆栈使用可能定义不明确(当然取决于优化标志和目标系统),因为 GCC 有时 有能力tail call 优化和函数 inlining(即使在函数不合格 inline!)和/或 function cloning 上。此外,一些少数 C standard library 函数(printfmemset、....)对于编译器来说是神奇的,它们可能会使用一些内部 builtin 函数来编译它们。最后用link-time optimizations编译了几个软件(以及越来越多的库)(使用-flto),然后各个函数的堆栈使用没有很好地定义(因为它们经常被内联)。

所以我不确定您的问题是否有任何精确 意义。你可以改写它并激励和改进它。

【讨论】:

我在主函数中打印 hello world。 .su 文件的输出是: - helloworld.c:4:5:main 16 static 而我想单独检查所有库函数。它只显示 main 函数的堆栈大小和用户定义函数的堆栈大小。有什么方法可以单独查找库函数的堆栈大小吗?

以上是关于如何从 c 代码中提取所有库函数的堆栈大小?的主要内容,如果未能解决你的问题,请参考以下文章

是否需要从堆栈中分配 C 可变长度数组?

请教ccs上如何使用file操作函数,heap应该如何设置

Linux AMD64 从复制的程序集中调用 C 库函数

计算机程序中的辅助库是啥?

如何从库函数中访问 c​​++ 中的 argc 和 argv

如何测量 C 中任意函数调用使用的堆栈数量?