简单介绍
调试是程序开发者必备技巧。如果不会调试,自己写的程序一旦出问题,往往无从下
手。本人总结 10 年使用 VC 经验,对调试技巧做一个粗浅的介绍。希望对大家有所帮助。
今天简单的介绍介绍调用堆栈。调用堆栈在我的专栏的文章 VC 调试入门提了一下,
但是没有详细介绍。
首 先 介 绍 一 下 什 么 叫 调 用 堆 栈 : 假 设 我 们 有 几 个 函 数 , 分 别 是
function1,function2,function3,funtion4 , 且 function1 调 用 function2 , function2 调 用
function3,function3 调用 function4。在 function4 运行过程中,我们可以从线程当前堆栈
中 了 解 到 调 用 他 的 那 几 个 函 数 分 别 是 谁 。 把 函 数 的 顺 序 关 系 看 ,
function4、function3、function2、function1 呈现出一种“堆栈”的特征,最后被调用的函数
出现在最上方。因此称呼这种关系为调用堆栈(call stack)。
当故障发生时,如果程序被中断,我们基本上只可以看到最后出错的函数。利用 call
stack,我们可以知道当出错函数被谁调用的时候出错。这样一层层的看上去,有时可以猜
测出错误的原因。常见的这种中断时 ASSERT 宏导致的中断。
在程序被中断时,debug 工具条的右侧倒数第二个按钮一般是 call stack 按钮,这个按
钮被按下后,你就可以看到当前的调用堆栈。
实例一:介绍
我们首先演示一下调用堆栈。首先我们创建一个名为 Debug 的对话框工程。工程创建
好以后,双击 OK 按钮创建消息映射函数,并添加如下代码:
void CDebugDlg::OnOK()
{
// TODO: Add extra validation here
ASSERT(FALSE);
}
我们按 F5 开始调试程序。程序运行后,点击 OK 按钮,程序就会被中断。这时查看
call stack 窗口,就会发现内容如下:
CDebugDlg::OnOK() line 176 + 34 bytes
_AfxDispatchCmdMsg(CCmdTarget * 0x0012fe74 {CDebugDlg}, unsigned int 1, int
0, void (void)* 0x5f402a00 `vcall'(void), void * 0x00000000, unsigned int 12,
AFX_CMDHANDLERINFO * 0x00000000) line 88
CCmdTarget::OnCmdMsg(unsigned int 1, int 0, void * 0x00000000,
AFX_CMDHANDLERINFO * 0x00000000) line 302 + 39 bytes
CDialog::OnCmdMsg(unsigned int 1, int 0, void * 0x00000000,
AFX_CMDHANDLERINFO * 0x00000000) line 97 + 24 bytes