C# 调用堆栈信息

C# 调用堆栈信息,c#,debugging,callstack,C#,Debugging,Callstack,在Visual Studio 2012中,我使用调试启动应用程序。我打开一些屏幕,然后关闭它。在这一点上,当我查看调用堆栈时,我可以看到我的应用程序中的起始点、打开/关闭屏幕的一些方法,以及许多不是来自我的应用程序的(外部)调用。我注意到我的应用程序中的许多调用都没有列出,尽管它们已经被执行了 我在我的应用程序中放置了一个断点。当应用程序到达断点时,我开始使用F11进入代码。基本上,它所做的是从循环中调用SomeMethod(断点在循环中设置) 当我使用F11进入SomeMethod时,我看到S

在Visual Studio 2012中,我使用调试启动应用程序。我打开一些屏幕,然后关闭它。在这一点上,当我查看调用堆栈时,我可以看到我的应用程序中的起始点、打开/关闭屏幕的一些方法,以及许多不是来自我的应用程序的(外部)调用。我注意到我的应用程序中的许多调用都没有列出,尽管它们已经被执行了

我在我的应用程序中放置了一个断点。当应用程序到达断点时,我开始使用F11进入代码。基本上,它所做的是从循环中调用SomeMethod(断点在循环中设置)

当我使用F11进入SomeMethod时,我看到SomeMethod列在调用堆栈中,但如果我点击F5,然后再次点击断点(在循环中),再次查看调用堆栈,SomeMethod将不再列出


那么,调用堆栈如何决定在其中显示哪些方法呢?我们如何才能得到已执行方法的完整列表?

调用堆栈不是已调用方法的列表,而是已调用但未返回的方法的列表

让我解释一下

我将首先给出一个简单的函数调用示例。运行程序时,调用函数。为此,它将参数和自身的位置推送到堆栈上。(现在位于堆栈的顶部)。然后调用函数,该函数将指令指针跳转到该函数的代码所在的位置。该函数将其参数从堆栈中提取出来(调用该函数是为了让它知道它们必须位于堆栈顶部),并运行其本地代码。完成后,它从堆栈中提取返回地址,并使用它返回指向调用此函数的位置的指令指针

现在在更复杂的情况下,任何函数都可以调用任何其他函数——它的工作原理完全相同,但现在堆栈将包含在最近调用的函数底部调用的第一个函数。因为您总是从堆栈的顶部获取,所以您将始终返回上次调用的位置


好的,当查看调试器中的调用堆栈时,您将看到在程序中所处位置之前进行的所有函数调用。在某个时刻,代码将返回到堆栈中列出的位置。但是,如果一个函数调用已经返回,那么它将不再在堆栈上,当该函数返回时,它已从堆栈中弹出。

我认为您对调用堆栈的实际含义有误解。每当一个方法调用另一个方法时,它在旧方法中的地址就会被推送到堆栈上。一旦它返回到该方法,它就会从堆栈中弹出,不再显示


它不是所有已调用方法的记录,而是当前执行块完成时执行将返回到的位置的列表。

调用堆栈仅显示特定线程当前“正在进行”(尚未退出)的方法。堆栈不包括已完成的方法

找出哪些方法运行(或未运行)的最简单方法是使用探查器。在VisualStudio中,它被称为“性能分析”(位于“分析”菜单下)

如果您不熟悉评测,我建议您使用“性能向导”(也在“分析”菜单上)。选择“Instrumentation”作为评测方法,因为这将为您提供函数调用计数(采样可能会错过不花太多时间的方法调用)


还值得一提的是,分析器不会给出方法调用的顺序。它将只计算它们。如果需要了解方法调用的顺序,则需要手动跟踪(通过在每个方法的开头和/或结尾添加代码来记录调用)。

调用堆栈是一种堆栈数据结构,用于存储有关活动子例程的信息。当方法完成时,它不再被认为是活动的,因此不会显示在调用堆栈上。基本上,您可以看到的调用堆栈是到达断点的方法调用的当前路径。

调用堆栈不显示以前执行过的方法。相反,它们显示了正在执行的方法调用树/堆栈/层次结构。第一种方法是您当前使用的方法-通常在其中设置断点或逐步使用调试器

您可以通过使用“Step out”命令看到这一点-这将直接跳转到调用堆栈中的下一个方法