1. 调用堆栈理解
首先介绍一下什么叫调用堆栈:假设我们有几个函数,分别是function1,function2,function3,funtion4,且function1调用function2,function2调用function3,function3调用function4。在function4运行过程中,我们可以从线程当前堆栈中了解到调用他的那几个函数分别是谁。把函数的顺序关系看,function4、function3、function2、function1呈现出一种“堆栈”的特征,最后被调用的函数出现在最上方。因此称呼这种关系为调用堆栈(call stack)。
2. 作用
- “调用堆栈”窗口可以查看当前堆栈上的函数或过程调用。
- “调用堆栈”窗口显示每个函数的名称和编写它所用的编程语言。函数或过程名可能伴随有可选信息,如模块名、行号、字节偏移量以及参数的名称、类型和值。 可以打开或关闭这些可选信息的显示。
- 一个黄色箭头标识执行指针当前所位于的堆栈帧。 默认情况下,该帧的信息显示在源、“反汇编”、“局部变量”、“监视”和“自动”窗口中。 如果想将上下文更改为堆栈上的另一个帧,可以在“调用堆栈”窗口中执行相应的操作。
- 当调试符号对部分调用堆栈不可用时,“调用堆栈”窗口也许就不能显示那部分堆栈的正确信息。
常用的场景:
当故障发生时,如果程序被中断,我们基本上只可以看到最后出错的函数。
利用call stack,我们可以知道当出错函数被谁调用的时候出错。这样一层层的看上去,有时可以猜测出错误的原因。
在程序被中断时,debug工具条的右侧倒数第二个按钮一般是call stack按钮,这个按钮被按下后,你就可以看到当前的调用堆栈。
3. 实例之堆栈演示
首先我们创建一个工程添加如下代码: 代码中test_c()函数被test_b()函数调用,test_b()被test_a()调用
#include <iostream>
using namespace std;
int test_c()//在此函数中设置断点
{
int k=9;
return k;
}
int test_b()
{
int k=test_c();
return k;
}
int test_a()
{
int k=test_b();
return k;
}
int main()
{
int k=test_a();
int t=0;
getchar();
return 0;
}
我们按F5开始调试程序。程序运行后,点击OK按钮,程序就会被中断。这时查看call stack窗口如下所示
图中,test_c()函数作为整个调用链中最后被调用的函数出现在call stack的最上方,紧接着就是test_b()、 test_a()等一些内部函数。
详细的可以直接看说明手册(最后一个链接)
参考 :
- http://blog.sina.cn/dpool/blog/s/blog_65cab32d01015d7d.html
- https://msdn.microsoft.com/zh-cn/library/a3694ts5(v=vs.90).aspx