`
huozheleisi
  • 浏览: 1234527 次
文章分类
社区版块
存档分类
最新评论

VC调试技术小技巧

 
阅读更多

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

在多线程程序中取得线程名和线程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版本中,编译器的优化作用,程序代码中的某些行可能不会被执

分享到:
评论

相关推荐

    VC的若干实用小技巧

    VC的若干实用小技巧,借助于一些调试等的小技巧,可以让你轻松的完成VC的工作。

    关于VC调试的几篇文章

    VC调试入门.doc 调试Release版本应用程序.doc 调试技巧之调用堆栈 - Call stack.doc 如何查看MFC源码.doc Release调试.doc VC++中使用Disassembly查看代码.doc 细谈VC程序调试的若干方法.doc

    VC6.0的18个实用小技巧

    很实用的各种小技巧,能让你的编程更方便。如:如何添加系统中Lib到当前项目,如何在Studio使用汇编调试。。。。

    绍VC6.0的18个实用小技巧

    容易被忽视但十分有用的小技巧,可以有效地减少编程调试时候的一些犯人的低级错误。

    VC与Labview、Matlab编程论文资料[2].rar

    这是VC与Labview、Matlab编程论文资料,全部为pdf格式,讲述有VC编程技巧、也有VC与Labview混合编程, VC与matlab混合编程,有365个,约500M,分成4个【独立】压缩包,如果想要全部的论文则需要下载全部压 缩包,...

    VC与Labview、Matlab编程论文资料

    这是VC与Labview、Matlab编程论文资料,全部为pdf格式,讲述有VC编程技巧、也有VC与Labview混合编程, VC与matlab混合编程,有365个,约500M,分成4个【独立】压缩包,如果想要全部的论文则需要下载全部压 缩包,...

    100个gdb小技巧

    UNIX及UNIX-like下的调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果你是在 UNIX平台下做软件,你会发现GDB这个调试工具相比于VC、z的优点是具有修复网络断点...这些小技巧都很好用。

    VC与Labview、Matlab编程论文资料[4].rar

    这是VC与Labview、Matlab编程论文资料,全部为pdf格式,讲述有VC编程技巧、也有VC与Labview混合编程, VC与matlab混合编程,有365个,约500M,分成4个【独立】压缩包,如果想要全部的论文则需要下载全部压 缩包,...

    Linux-operator-new-delete.rar_Operator Down_VC debug技巧_内存泄漏

    在 windows 下使用 VC 编程时,我们通常需要 DEBUG 模式下运行程序,而后调试器将在退出程序时,打印出程序运行过程中在堆上分配而没有释放的内存信息,其中包括代码文件名、行号以及内存大小。该功能是 MFC ...

    VC学习大纲 VC学习讲义

    Windows程序运行原理及程序编写流程,窗口产生过程,句柄原理,消息队列,回调函数,窗口关闭与应用程序退出的工作关系,使用VC++的若干小技巧,stdcall与cdecl调用规范的比较,初学者常犯错误及注意事项。...

    使用VC6.0对C语言程序进行调试的基本手段分享

    主要介绍了用VC6.0开发c语言程序的时候调试代码的一些小技巧,需要的朋友可以参考下

    Visual C++音频视频处理技术及工程实践(分卷0)

    12.3.3 使用VC调试MMX/SSE 2程序 470 12.4 MMX/SSE 2开发常见问题 472 12.4.1 制订计划 472 12.4.2 哪部分代码可使用MMX技术改进 473 12.4.3 代码是浮点型还是整型 473 12.4.4 EMMS准则 474 12.4.5 CPUID的检测MMX...

    Visual C++音频视频处理技术及工程实践(含源码2/2)

    12.3.3 使用VC调试MMX/SSE 2程序 470 12.4 MMX/SSE 2开发常见问题 472 12.4.1 制订计划 472 12.4.2 哪部分代码可使用MMX技术改进 473 12.4.3 代码是浮点型还是整型 473 12.4.4 EMMS准则 474 12.4.5 CPUID的...

    Visual C++音频视频处理技术及工程实践地址

    12.3.3 使用VC调试MMX/SSE 2程序 470 12.4 MMX/SSE 2开发常见问题 472 12.4.1 制订计划 472 12.4.2 哪部分代码可使用MMX技术改进 473 12.4.3 代码是浮点型还是整型 473 12.4.4 EMMS准则 474 12.4.5 CPUID的...

    Visual C++音频/视频处理技术及工程实践 (分卷1)

    12.3.3 使用VC调试MMX/SSE 2程序 470 12.4 MMX/SSE 2开发常见问题 472 12.4.1 制订计划 472 12.4.2 哪部分代码可使用MMX技术改进 473 12.4.3 代码是浮点型还是整型 473 12.4.4 EMMS准则 474 12.4.5 CPUID的检测MMX...

    Visual C++音频视频处理技术及工程实践(分卷9)

    12.3.3 使用VC调试MMX/SSE 2程序 470 12.4 MMX/SSE 2开发常见问题 472 12.4.1 制订计划 472 12.4.2 哪部分代码可使用MMX技术改进 473 12.4.3 代码是浮点型还是整型 473 12.4.4 EMMS准则 474 12.4.5 CPUID的检测MMX...

    Visual C++ 音频/视频 处理技术及工程实践(分卷3)

    12.3.3 使用VC调试MMX/SSE 2程序 470 12.4 MMX/SSE 2开发常见问题 472 12.4.1 制订计划 472 12.4.2 哪部分代码可使用MMX技术改进 473 12.4.3 代码是浮点型还是整型 473 12.4.4 EMMS准则 474 12.4.5 CPUID的检测MMX...

    Visual C++音频视频处理技术及工程实践(分卷7)

    12.3.3 使用VC调试MMX/SSE 2程序 470 12.4 MMX/SSE 2开发常见问题 472 12.4.1 制订计划 472 12.4.2 哪部分代码可使用MMX技术改进 473 12.4.3 代码是浮点型还是整型 473 12.4.4 EMMS准则 474 12.4.5 CPUID的检测MMX...

    Visual C++音频视频处理技术及工程实践(分卷6)

    12.3.3 使用VC调试MMX/SSE 2程序 470 12.4 MMX/SSE 2开发常见问题 472 12.4.1 制订计划 472 12.4.2 哪部分代码可使用MMX技术改进 473 12.4.3 代码是浮点型还是整型 473 12.4.4 EMMS准则 474 12.4.5 CPUID的检测MMX...

    Visual C++音频/视频处理技术及工程实践(分卷2)

    12.3.3 使用VC调试MMX/SSE 2程序 470 12.4 MMX/SSE 2开发常见问题 472 12.4.1 制订计划 472 12.4.2 哪部分代码可使用MMX技术改进 473 12.4.3 代码是浮点型还是整型 473 12.4.4 EMMS准则 474 12.4.5 CPUID的检测MMX...

Global site tag (gtag.js) - Google Analytics