如何使用Visual C++子集搜索主题

开发 后端
各种高级断点的设置在MSDN中有详细的介绍,请在Visual C++子集下搜索主题Using Breakpoints: Additional Information并阅读相关内容。

在Windows平台上的实现就有若干种,比较常用的有Visual C++ 6.0附带的Visual C++子集实现,和Borland C++ Builder附带的C++编译器实现,看完本文你肯定有不少收获,希望本文能教会你更多东西。

如果程序并不是每次运行到断点处都会发生错误,那么不停地在调试器和应用程序之间穿梭很快就会让人厌倦,这时高级断点就派上了用场。从本质上来讲,高级断点允许你将某些智慧写入到断点中,让调试器在执行到断点处时,只当程序内部状态符合你指定的条件时才在断点处中断程序运行,并切换到调试器中。按下Alt+F9快捷键弹出Breakpoints对话框,浏览一下对话框发现该对话框分为Location、Data和Messages三页,分别对应三种断点:

1. 位置断点:我们通常使用的简单断点均为位置断点,我们还可以设置断点在某个二进制地址或任何函数上,并通过指定各种限定条件来增强位置断点的功能。

2. 表达式和变量断点:调试器会让程序一直运行,直到满足所设的条件或者指定数据更改为止。在Intel CPU上,这两种断点都尽可能通过CPU的特定调试寄存器使用一个硬件断点,如果能够使用调试寄存器,那么程序将能够全速运行,否则调试器将单步执行每个汇编指令,并每步都检查条件,程序的运行速度将极其缓慢甚至无法运行。

3. Visual C++子集断点:使用消息断点,可以让调试器在窗口过程接收到一个特定的Windows消息时中断。消息断点适用于C SDK类型的程序,对于使用MFC等C++类库的程序(应该是绝大多数)来说,消息断点并不实用,可以变通地使用位置断点来达到同样效果。

调用堆栈

有时候我们并不清楚应该在哪里设置断点,只知道程序正在运行就突然崩溃了,这时候如何定位到出错地点呢?这时的选择就是查看调用堆栈,调用堆栈可以帮助我们确定某一特定时刻,程序中各个函数之间的相互调用关系。#t#

方法是当程序执行到某断点处或者程序崩溃,控制权转到调试器后,按下Alt+7快捷键,弹出Call Stack窗口,你可以看到当前函数调用情况,当前函数在最上面,下面的函数依次调用其上面的函数。在Call Stack窗口的弹出菜单上选择Parameter Values和Parameter Types可以显示各个函数的参数类型和传入值。

使用跟踪工具

有些时候,我们希望了解程序中不同函数之间的协作关系,或者由于文档的缺失,希望能够确认函数在不同情况下被调用时的传入参数值。这时使用断点功能就过分麻烦,而调用堆栈只能查看当前函数的被调用情况,一种较好的方法就是使用TRACE宏以及相对应的工具。

程序(Debug版)运行中,一旦运行到Visual C++子集,就会向当前Windows系统的调试器输出TRACE宏内指定的字符串并显示出来,当在Visual C++环境中调试运行(按F5键)程序时,可以在Output窗口的Debug页看到TRACE宏的输出内容。

实际上,TRACE宏是封装了Windows API函数OutputDebugString的功能,有些辅助工具可以在不惊动Visual C++调试器的前提下,拦截程序中TRACE宏的输出内容,比如《深入浅出MFC》的附录中提到的Microsoft System Journal(MSJ)1996年1月的C/C++专栏介绍的TraceWin工具(在较老版本的MSDN中可以找到源代码和文档)以及功能强大的免费工具DebugView。

使用TRACE宏,我们可以轻松了解程序中各个函数之间的相互协作关系和被调用的先后顺序和时间,进一步说,你能够完全掌握程序的执行流程。***请注意,TRACE宏会对程序效率有所影响,所以,当前不用的TRACE宏***删除或者注释掉。

 阅读程序的技巧

对于程序员来说,无论是学习还是工作,经常要阅读其他程序员的源代码,如何快速领悟程序的思想,洞悉程序的结构和各个组成部分的功能,进而全面掌握程序所涉及的方方面面,是程序员很重要的一项基本技能。下面介绍一些常用的技巧。

从功能、界面入手Visual C++子集

一个完整的应用程序或者系统是由若干相对独立的功能构成,这些功能反应在与用户交互的图形界面上,就是各种菜单命令、工具栏按钮命令等等。所以如果当前只对程序的某几个功能感兴趣,可以在程序中找到这些菜单命令、按钮命令等的ID响应函数,以此为起点,逐步深入到程序内部,直到完全理解该功能的实现为止。此过程所花费的时间,很大程度上取决于程序员对调试技术的掌握程度。

需要强调的是,在不熟悉程序核心结构和实现技术的情况下,直接采用该方法探究程序,当逐步深入到程序核心时,涉及的程序模块数量会急剧增长,理解难度也会骤然增大;一旦你对程序核心结构和实现技术了然于胸,采用该方法探究程序,会有势如破竹之感觉。

砍去枝叶,只留主干

前面已经提到,无论如何,最终你都要掌握程序核心结构和实现技术。如何掌握呢?方法是首先将拿到的程序进行完整的备份,然后将次要功能都从程序中去掉,只留下的必须的部分。去除次要功能是一个反复多次的过程,花费的时间取决于程序员对行业知识的理解程度、编程技术的高低和经验的多少。

经常遇到无法在短时间内判断某个模块是否次要的情况(随着对程序的理解逐渐加深,以及经验和技术的积累,这种情况会越来越少),这时候建议直接将该模块去除,然后重新编译连接程序,运行程序,看程序运行是否正常。

以上介绍的两种方法是使用比较频繁的,Visual C++子集可以相互结合,交替使用。但无论采用什么方法探究阅读程序,都不要指望能够不费任何气力,花费一两个钟头就能够将上万行的程序探究个明白。

责任编辑:chenqingxiang 来源: 天极
相关推荐

2010-01-19 14:54:58

Visual C++

2010-01-20 10:49:29

Visual C++界

2010-01-08 17:13:46

Visual C++环

2010-01-14 14:17:20

Visual C++

2010-01-26 15:51:06

C++变量

2010-01-18 15:40:37

Visual C++工

2010-01-15 14:52:33

Visual C++

2010-01-12 09:59:08

Visual C++

2009-11-12 10:05:09

Visual C++

2009-11-12 11:00:56

Visual C++

2010-01-13 10:45:44

Visual C++

2010-01-19 14:39:22

C++ Builder

2010-01-25 09:50:58

C++函数对象

2010-01-22 14:20:17

Visual C++

2010-01-18 14:41:52

Visual C++开

2011-03-30 14:49:00

Visual C++CPU

2010-01-26 14:10:22

Visual C++

2010-01-18 15:19:41

Visual C++开

2010-01-14 13:39:45

Visual C++优

2010-01-26 13:14:48

点赞
收藏

51CTO技术栈公众号