VC调试技术小技巧

来源:互联网 发布:最有味道的av 知乎 编辑:程序博客网 时间:2024/05/21 09:45

 

     在一个大型项目的开发中,偶遇到多线程轮询操作出错,为了解决问题,查阅了一些相关资料,结合实际程序调试中的一些经验,把几个调试中的小技巧总结如下,希望对同行们有所帮助。

   在多线程程序中取得线程名和线程ID

   由于多个线程中的执行是不确定的,所以对于多线程的调试是一件比较困难的事情,而C++编译器提供了直接获取系统级信息的能力,对于每个线程来说,都有一个称为TIB的数据结构存储它本身的信息,通过在调式过程中直接获取TIB的信息,达到判断错误位置和错误原因的目的。

   根据Matt Pietrek19965月提出的TIB概念,运行在WIN32系统中每一个线程都有一个TIB,而且FS 寄存器指向TIB的地址。并且通过查阅一些相关的程序代码,下面是来自CodeGuru上的一段代码,它包含了活动线程TIB地址的函数以及TIB的具体应用函数:

 

 

    使用过程就是在线程回调函数中调用XTIB::SetThreadName(szThreadName)函数,调试时,在此函数处设置断点,在Watch窗口中键入(char*)(DW(@TIB+0x14))DW(@tib+0x24)就可以取得当前线程名和线程ID。如下图:

获得系统函数错误代码

     一个Windows函数返回的错误代码对确认函数为什么会运行失败常常很有用,Microsoft公司编译了所有可能错误代码的列表,并且为 每个错误代码分配了一个32位的号码。从系统内部来讲,当一个windows函数检测到一个错误时,它会使用所以个称为线程本地存储器[2]thread-local storage)的机制,将相应的错误代码号码与调用的线程关联起来。这将使线程能独立的运行,而不会影响各自的错误代码。当函数返回时,它的返回值就能指明一个错误已经发生,若要确定这个错误,通过调用GetLastError()函数可以取得线程的32位错误代码(一个DWORD类型变量的值)。当取得32位错误代码后,必须将其转换为有用的某种对象,而WinError.h头文件中包含了Microsoft公司定义的错误代码列表。从此文件中可得到一个错误有3种表示方法:一个消息ID,消息文本和一个号码,具体的细节内容可查阅WinError.h头文件。

   值得注意的是当Windows函数运行失败时,应该立即调用GetLasstError函数。如果在一个函数运行失败后,还调用了其他的函数,则其错误代码就可能被改写。

   在进行调试时,在VC6中可以配置Watch窗口,以便始终显示错误代码的号码和该错误的描述。要实现这个,必须在Watch窗口的 某一行键入“@err,hr”。这样就能始终显示当前执行的函数返回的错误代码。如下图:

     同时VC6中还提供了一个Error Lookup 的小工具,可以将相应的错误代码转换成文本描述。见下图:

 

  而且Windows本身也提供了诸如FormatMessage一类的函数,可以把错误代码转换成文本描述,反馈给用户,这里不一一详述。

 

     自定义函数错误

    同样,你也可以自己编写的函数向其他的调用者显示错误代码。这可以通过两种方式实现,

    第一,你可以使用WinError.h头文件中已经存在的32位错误代码,通过SetLastError函数来实现。

   第二,是如果WinError.h头文件中已经存在的32位错误代码都不能表示你的错误信息,那么你可以自定义自己的32位错误返回代码。定义错误代码时,必须明白错误代码域,如下图:

 

                            错误代码域

   要注意的是用户自定义错误代码必须把错误代码域中的29位设置为1,实现办法就是添加一个错误代码的宏定义,然后通过和第一种情况一样设置就可以了。

 

 Release版本的调试

     在很多程序员的观点中,只有Debug版本才能调试,其实对于Release版本的调试是一样可以进行的,有人也许会说,在Debug版本下调试就够了,能在Debug版本下运行很好的程序在Release版本下是不会有问题的,其实这个观点是错误的,我在写程序的过程中就遇到过很多次,一个程序在Debug下能很好的运行,但在Release下运行就出错,检查原因就是缓冲区越界,如果能在Release版本下调试的话,就能很快的找到问题,其实,Release版本的调试是很简单的,只要修改一下VC编译选项的设置就可以实现了。具体实现方法如下:

1、  打开VC集成环境——>Project——>Setting对话框。

2、  Serttings For组合框中选择All Configuration选项。

3、  选中C/C++ Tab,Debug info组合框中选择Program Database选项。

4、  切换到Link Tab,Category组合框选择Debug选项,然后选中下面的debug info 检查框和Microsoft Format 标志。

  在设定完成后,你就能够象调试DEBUG版本一样调试你的Release版本了,不过要注意的是,由于在Release版本中,编译器的优化作用,程序代码中的某些行可能不会被执