调用堆栈信息

时间:2013-10-11 17:04:50

标签: c# debugging callstack

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

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

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

那么,Call Stack如何决定在其中显示哪些方法?我们如何才能获得已执行的完整方法列表?

5 个答案:

答案 0 :(得分:3)

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

让我解释一下

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

现在在更复杂的情况下,任何函数都可以调用任何其他函数 - 它将完全相同但现在堆栈将包含在最近调用的函数底部调用的第一个函数。因为你总是从堆栈的顶部开始,所以你将始终返回到最后一次调用的位置。

好的,所以当在调试器中查看调用堆栈时,您会看到所有函数调用先前到您在程序中的位置。在某些时候,代码将返回到堆栈中列出的位置。但是,如果函数调用已经返回,它将不再存在于堆栈中,当该函数返回时,它已从堆栈中弹出。

答案 1 :(得分:2)

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

找出运行(或不运行)方法的最简单方法是使用分析器。在Visual Studio中,它被称为“性能分析”(位于“分析”菜单下)。

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

还要提到的是,探查器不会给出方法调用的顺序。它只计算它们。如果您需要知道方法调用的顺序,则需要手动跟踪(通过在每个方法的开头和/或结尾添加代码来记录调用)。

答案 2 :(得分:2)

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

你可以通过使用'Step out'命令来看到这一点 - 这会直接跳转到调用堆栈中的下一个方法。

答案 3 :(得分:0)

我认为你对call-stack实际上是什么有误解。每当方法调用另一个方法时,旧方法中的地址就会被压入堆栈。一旦它返回到该方法,它就会从堆栈弹出,不再被看到。

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

答案 4 :(得分:0)

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