• VC 调试版(Debug Version)和发行版(Release Version)


    调试是纠正或修改代码,使之可以顺利地编译、运行的过程。为此,VC IDE提供了功能强大的调试和跟踪工具。

    1.1.1 调试版(Debug Version)和发行版(Release Version

    开发环境总是为你的工程创建调试版和发行版。在调试版里,我们排查各种可能的程序错误,然后制作成发行版以获得较好的信息。这就是调试版与发行版的区别:前者包含了较多调试信息,最终执行文件较大,性能较差;后者最终执行文件较小,性能更好。具体地讲,发行版和调试版区别有:

    1.       调试版下,可以使用诊断和跟踪宏,如ASSERTTRACEMFC类的DUMP功能也定义在调试版下。

    2.       额外的变量初始化。编译器会自动将你未初始化的变量逐每字节赋值为0xCC

    3.       内存分配监视。在调试版下,在堆上分配的内存都会记录,做额外的初始化(0xCD),在释放时,会将其内容逐字节置0xFD

    怎样配置调试版[C1] 或发行版?

    调试版和发行版都可以从 Build | Configurations中增加,或者当这两个配置已存在的情况下,从Project | Settings命令下进行配置。两者在配置上主要有以下不同:

    1. 两个版本应该配置成不同的输出文件夹。这在Project | Settings | General中的两个编辑框中设定。

    2. 调试版下,程序应该链接Debug版的c运行时库、禁止代码优化,并在C++属性页中的Preprocessor类别中加上预定义标识符_DEBUG。在Link属性页中的Debug类别中,选中DebugInfoMicrosoft Format选框。

    4.       发行版下,程序应该链接Release版的c运行时库、设置代码优化,不定义_DEBUG标识符,去掉DebugInfo选框中的选择。

    1.1.2 排除编译错误

    VC6.0的编译器可以报告大约1100个左右的错误,这还不包含警告。而在编译和调试过程中我们还不仅仅遇到编译错误,也可能遇到链接错误和其他错误,因此我们只能讲一些很常见、很重要的编译错误。对我们没有列出来的编译错误,解决它的最好办法是,在output窗口中将光标定位在输出行,然后按F1键以获得MSDN的帮助。如果MSDN的版本与你的VC不兼容,那么你可以用获得到Error xxxx作为关键字在MSDN中搜索。目前这些错误的说明帮助出现在Visual C++ Programmer's Guide中的Build Errors条目下。

    并非错误

    形如“Loaded 'C:WINNTsystem32gdi32.dll', no matching symbolic information found.”这样的报告不是错误。一般情况下,我们只需要跟踪自己的源代码,检查在那里发生了什么错误。但有时候我们也想看看,如果一个错误报告在系统DLL里时究竟是怎么回事。Microsoft不愿意在系统DLL中包含调试信息,因此它提供调试符号帮助你跟踪。随VC6.0发行的有一个调试符号包,但其内容可能不能跟得上你操作系统版本。如果你需要适合你操作系统版本的调试符号,请到微软更新网站上下载。

    l       LNK2001错误

    LNK2001错误报告一个不能识别的外部标识符。通常你使用一个函数或外部变量,都必须事先给出其声明,否则就会产生这样一个错误。可以从以下几个方面寻找原因:

    1.       使用内联函数,但该内联函数定义在.cpp文件中,而不是在.h文件中。

    2.       声明了函数或外部变量,但找不到它们的定义。

    3.       程序入口设置错误,并且进一步提示_WinMain@16': Unresolved External Symbol或类似错误。在Windows程序中,程序并不是最先从WinMain()Main()这样的函数处开始执行,而是从WinMainCRTStartup()或MainCRTStratup函数处开始执行。这四个函数(实际上是8个,每个函数都有UNICODE版和单字节版)必须配套。如果进入点是WinMainCRTStartup (),则它期待在你的程序中找到一个WinMain()函数,如果找不到,则发生上述错误。

    4.       在程序中使用了线程启动函数_beginthread,但选择的链接库为LIBC.LIB

    其他错误见MSDN

    1.1.3 断点和跟踪

    编译错误都是静态的,更多的错误发生在运行时。为了排除运行时的错误,首先需要的是能够使正在运行的代码停下来。VC6.0提供了多种断点设置。

    l       位置断点

    l       条件断点:可以设置以下条件为真时中断程序

    1.       单变量值改变时

    2.       单变量值判断条件中断,如K>0i == 5

    3.       数组单元素或多元素值改变或值判断条件中断。

    4.       指针:指针变量改变或指针所指内容改变

    5.       监视固定内存值变化

    6.       监视寄存器中值的变化,如 cs == 0等。

    也可以直接输入断点设置表达式,其语法是:

    Advanced Syntax 详解

    {[function],[source],[exe] } location

    {[function],[source],[exe] } variable_name

    {[function],[source],[exe] } expression

     

    括在{}对中的是上下文设置,这三项中任意一项都可省略,但省略前面的项时,应注意保留逗号。如下面的设置

    是错误的:

    {File.c, File.exe} .143 - Bad

    正确的设置如

    {Fun} .143 这样在函数Fun的第143行设置了一个断点。

     

    更详细的说明见下面的举例:

    {[function],[source],[exe] }  .100 - A line number (this may not work with some languages)

    {[function],[source],[exe] }  @100 - A line number (this works for all languages)

    {[function],[source],[exe] }  Traverse - A function name

    {[function],[source],[exe] }  CMyWindow::OnCall - A function name

    {[function],[source],[exe] }  00406030 - A memory address (decimal)

    {[function],[source],[exe] }  0×1002A - A memory address (hexadecimal)

    {function,[source],[exe] }     Label - A statement label. The context must include function since

    Label is visible in the function’s scope.

     

    更详细的帮助,查看Visual C++ Programer’s GuidSetting Breakpoints When Values Change or Become True主题。

    l       消息断点

    l       异常断点

    当程序发生异常时,我们应该立即停下来,看看发生了什么事情。默认地,当一个异常发生时,Debugger 将异常信息写到Output 窗口中,并根据你的选择决定是否立即中断程序。这个设置在Debug菜单中的Exceptions选项中提供。这里提供了两个选项Stop AlwaysStop If Not Handled。当Stop If Not Handled被选中时,debugger仅仅往Output窗口中输出一条信息,而并不中止程序,除非没有这个异常最后也得不到处理。在有些情况下,这会是一个有些晚的时机。当Stop Always被选中时,debugger会在异常处理代码接管以前就中断程序。

    1.1.4 查看和修改程序运行状态

    开发环境提供了一系列的查看方式来临视甚至修改程序的运行状态。总共提供了六种查看窗口:

    l       Watch窗口

    Watch窗口用来查看和解码中间变量,并允许你修改变量的值。Watch窗口共有四个Tab。每个Tab都是一个ListView,由两栏组成。左边一栏为变量名,右边一栏则为变量取值。只要在变量名栏输入变量名并回车,就可以得到当前变量的值。下面是一些特殊的用法:

    1.       列出数组中前n个元素的值:arrn

    2.       查看UNICODE编码的字符串值:strsu

    3.       已知消息值,查对应的宏:messageValuewm

    4.       查看窗口类标志(Window class flag):flagValuewc

    5.       查看当前线程最后错误报告:@errhr

    6.       查看COM库最后错误报告:@hres,hr

    7.       查看当前寄存器值,把寄存器名当作变量名输入就可以了。

    直接在右边栏输入新的取值,就会修改该变量的取值并发生作用。

    l       Variables窗口

    这个窗口始终跟踪当前上下文中重要的变量取值。但不能增加对变量的跟踪。它包含三个Tab

    Auto窗口跟踪当前声明或前一个声明中使用的变量,当你从一个函数调用中跳出时,还可以显示函数的返回值。

    Locals窗口显示对当前函数来说是局部的变量的取值。

    This窗口显示this指针所指对象取值。

    此外,在Variables窗口的上部,还有一个Context的组合框,可以用来切换当前查看的上下文。

    l       CallStack窗口

    这个窗口显示了函数调用的情况。当你的程序出现一个断言时,你可以用这个窗口把函数调用顺序调出来,并且可以知道调用时传递参数的情况。双击窗口中列出的函数,可以定位到源代码中。

    l       Memory窗口

    Memory窗口的上部是一个地址输入框。你可以在这里输入0×00400000,因为这时进程的起始点,所以毫不奇怪,你会看到MZ这两个字。Memory窗口支持定制显示格式,并支持表达式。

    Memory窗口的下面窗口处按右键,会出现一个菜单,允许你按单字节、双字节十六进制或四字节十六进制来显示内存的内容。

    如果你愿意麻烦一点,还有办法得到更准确的显示。点Tools | Options,选择Debug属性页,在这里可以决定以什么形式显示内存内容以及从什么地址开始显示。这里提供了14种格式选项。此外,你还可以输入一个地址表达式。比如,如果要知道当前栈顶的情况,在这里输入ESP

    l       Disassembly窗口

    这个窗口可以用跟踪优化代码,或者是复杂表达式。

    l       Registers窗口

    Registers窗口显示所有寄存器值,并允许你修改。它与Watch窗口的区别是,你不需要记住寄存器名,它总是把所有寄存器值给你列出来。

    1.1.5 使用断言和诊断[1]

    VC提供了两个断言宏:ASSERTVERIFY。两者的区别是,在发行版中,ASSERT行不会执行,因为在发行版中,ASSERT宏被定义成

    #define ASSERT /##/

    这样这行代码被注释掉,从而不会被编译。VERIFY宏在发行版中被定义成

    #define VERIFY

    这样VERIFY后面的代码仍然加入编译,从而得到执行。

    在你掌握了这两个断言的区别后,我们将只讲述ASSERT宏。ASSERT是一个带参宏,其参数允许是一个表达式。当表达式的值为假时,程序发生中断并提示你是否进行调试。

    除了使用条件判断表达式外,ASSERT(0)也很有用。它始终引起一个断言错,并提示你是否调试。你可以把它放在一些你不期望程序运行到达的路径上,如果事情一旦发生,则可以直接进行调试。

    VC还提供TRACE宏,以及它的姊妹宏TRACE0TRACE1TRACE2TRACE3TRACE宏的语法类似于printf,包括格式字符串的规定也是一致的。后面三个宏限定你使用一个格式字符串和一至三个变量。TRACE输出到Output窗口,如果工具MFC TRACER中设置为允许的话。

    MFC还提供了对象诊断工具,即名为Dump的函数。MFC库中每个从CObject继承的类都有Dump的能力。如果你从MFC类库中派生了某个类,在有必要的情况下,最好重载这个函数。要记住,你重载的函数应该调用基类的Dump函数。另外,Dump函数只在调试版下可用。因此重载的函数也应该括在#ifdef _DEBUG宏中。

  • 相关阅读:
    修改linux资源限制
    Windows 建立链接
    Java & ant环境变量配置
    Linux 配置IP
    Spring-MVC 访问静态资源
    Maven 安装与配置
    OIM同步OID(OID-Connector 9.0.4.12)
    Connector|OIM向IBM TDS推送账号(LDAP3)
    TopFreeTheme精选免费模板【20130704】
    30+简约和平铺的WordPress复古主题
  • 原文地址:https://www.cnblogs.com/kungfupanda/p/9006034.html
Copyright © 2020-2023  润新知