调用堆栈信息

本文关键字:信息 堆栈 调用 | 更新日期: 2023-09-27 18:34:53

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

我在应用中放置了一个断点。当应用程序命中断点时,我开始使用 F11 单步执行代码。基本上它的作用是,它从循环中调用 SomeMethod(断点在循环中设置(。

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

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

调用堆栈信息

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

让我解释一下

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

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

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

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

确定哪些方法运行(或未运行(的最简单方法是使用探查器。 在Visual Studio中,它被称为"性能分析"(位于"分析"菜单下(。

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

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

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

您可以使用"Step Out"命令看到这一点 - 这将直接跳转到调用堆栈中的下一个方法。

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

我认为

您对调用堆栈实际上是什么有误解。 每当一个方法调用另一个方法时,它在旧方法中的地址都会被推送到堆栈上。 一旦它返回到该方法,它就会从堆栈中弹出,不再可见。

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