c - 如何测量 Visual Studio 中 C 程序的函数堆栈大小?

标签 c visual-studio optimization memory profiling

我有一个非常大的 C 项目,目前存在于 Visual Studio 解决方案中。我正在使用 Visual Studio 2015。项目的每个组件都包含在其自己的 Visual Studio 项目中。每个组件都有一个“init”和一个在 while 循环中调用的“run”函数。我特别有一个组件,我想在其中测量其“运行”功能的堆栈大小。理想情况下,我会将特定参数更改为该运行函数,并查看它如何进一步影响内存(因此运行多个分析)。对于 GCC,我发现您可以使用 fstack-usage,这几乎完全符合我的要求:程序中每个函数的内存消耗(即堆栈大小)。然而,我在网上找到的大多数解决方案仅适用于 Linux 系统。我也非常希望不迁移我的 VS 解决方案到不同的平台。

然而,在 VS 中,我还没有找到工具、API 或任何类似的东西。 VS Performance Profiler 有点做我想做的事,但它不提供每个函数的内存,只提供整个过程的内存,这对于分析组件来说并不理想-基于项目。 Visual Studio 中是否有可以测量所有可能函数的函数堆栈大小的工具或方法?我不介意自己编写工具,但我更喜欢相对简单的工具。

我也应该在这里声明,我不想要整个进程内存或调用堆栈大小。 IE。它应该打印出这样的东西:

Function Name | Stack Size
--------------|------------
a_Run         | 10.5 KB
b_Run         |  5.7 KB

谢谢!

最佳答案

一种非常笨拙/hacky 的方法可能是在调用 run 函数之前检测调用堆栈的开始,并从开始处将水印放在固定范围内。然后,当 run 完成时,再次遍历带有水印的内存范围,并检测水印在哪里仍然存在以及它被 run 函数的实际堆栈使用情况替换的地方。

要检测堆栈的开始,您可以执行以下操作:

// before calling run
#define MAX_CALL_STACK 1024
volatile int start; // declare just before calling run
// fill from &start to something with a known pattern.
// the trick is to ensure no other stack allocation is performed here
register int i;
register int &add = &start;
for (i = 0 i<MAX_CALL_STACK ;i++)
{
  *add = 0xdeadbeef; a++;
}    
run(); // this will replace deadbeaf values up to a given address
printf ("run call stack start address:0x%p",(void*)&start);

应检查编译的水印代码以确保它确实使用了寄存器并且在调用运行之前没有声明任何其他局部变量。

我没有展示如何检测 0xdeadbeef 的范围,但这不会那么复杂。

关于c - 如何测量 Visual Studio 中 C 程序的函数堆栈大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59613380/

相关文章:

c - printf语句问题

c++ - 两个 DLL 之间的堆损坏

performance - perf stat 输出解释

c - 如何使用 C union 来使多个命名变量和另一个更大的命名变量相等?

c - 无法理解 C 基础知识

c - 如何将 "-lm"(LDFLAGS) 正确添加到此 Makefile 中?

visual-studio - Visual Studio : COMException opening project file

node.js - 如何在Visual Studio 2012中打开njsproj项目

c# - 连接字符串的最有效方法?

java - 在 C、C++ 和 Java 中提升/重新排序 : Must variable declarations always be on top in a context?