铅笔

在你的害怕中坚持的越多,你就会越自信
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

调试技巧之调用堆栈

Posted on 2017-10-19 23:32  黑色の铅笔  阅读(7502)  评论(0编辑  收藏  举报

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