简体   繁体   English

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

[英]How to measure function stack size for a C program in Visual Studio?

I have a very large C project that currently exists in a Visual Studio solution.我有一个非常大的 C 项目,目前存在于 Visual Studio 解决方案中。 I am using Visual Studio 2015. Each component of the project is contained within its own Visual Studio Project.我使用的是 Visual Studio 2015。项目的每个组件都包含在自己的 Visual Studio 项目中。 Each component has an "init" and a "run" function that is called in a while loop.每个组件都有一个“init”和一个在while循环中调用的“run”函数。 I have one component in particular where I want to measure the stack size of its "run" function.我有一个组件,特别是我想测量其“运行”函数的堆栈大小。 Ideally, I'd change a specific parameter to that run function and see how it impacts memory further down the line (so run multiple profiling's).理想情况下,我会更改该运行函数的特定参数,并查看它如何进一步影响内存(因此运行多个分析)。 For GCC, I've found that you can use fstack-usage, and that yields almost exactly what I'd want: the memory consumption (ie stack size) of each function in the program.对于 GCC,我发现您可以使用 fstack-usage,这几乎完全符合我的要求:程序中每个函数的内存消耗(即堆栈大小)。 Most solutions I've found online however apply to Linux systems only.我在网上找到的大多数解决方案仅适用于 Linux 系统。 I'd also strongly prefer to not migrate my VS solution to a different platform.我也非常希望不要将我的 VS 解决方案迁移到不同的平台。

In VS, however, I haven't found a tool, API, or anything similar.但是,在 VS 中,我还没有找到工具、API 或任何类似的东西。 The VS Performance Profiler kind of does what I want it to, but it doesn't give the memory of each function, just the memory of the entire process, which isn't ideal for profiling a component-based project.该VS性能分析器那种做什么,我想它,但它并没有给每个功能的内存,整个过程,这是不理想的剖析一个基于组件的项目只是记忆。 Is there a tool or method in Visual Studio where I can measure the function stack size for all possible functions? Visual Studio 中是否有工具或方法可以测量所有可能函数的函数堆栈大小? I don't mind having to write my own tool but I'd prefer something relatively simple.我不介意必须编写自己的工具,但我更喜欢相对简单的东西。

I should state here as well that I don't want the entire process memory, or the call stack size.我也应该在这里声明我不想要整个进程内存或调用堆栈大小。 Ie it should print out something like this:即它应该打印出这样的东西:

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

Thanks!谢谢!

A quite hugly/hacky way could be to detect the start of the call stack just before calling the run function and put a watermark in a fixed range from the start.一种非常巧妙/笨拙的方法可能是在调用run函数之前检测调用堆栈的开始,并在开始时将水印放在固定范围内。 Then when run is finished, walking again the watermarked memory range, and detecting where the watermark is still present vs where it's been replaced by the actual stack usage of the run function.然后当run完成时,再次遍历带水印的内存范围,并检测水印仍然存在的位置与运行函数的实际堆栈使用情况所取代的位置。

To detect the start of stack you can do:要检测堆栈的开始,您可以执行以下操作:

// 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);

The compiled watermarking code shall be checked to ensure it indeed uses registers and does not declare any other local variable before calling run.编译后的水印代码应该被检查以确保它确实使用了寄存器并且在调用 run 之前没有声明任何其他局部变量。

I did not show how to detect the expanse of 0xdeadbeef but this shall not be that complex.我没有展示如何检测0xdeadbeef的范围,但这不会那么复杂。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM