昨天在用VC调试cnbook时碰到两个有个性的bug:
- bug1仅在直接运行Release版本时出现,用F5运行Debug版本或Release版本都不会出现。
- bug2仅在用F5运行Debug版本时出现,直接运行Release版本不会出现。
1 bug1和Release版本调试
这个bug不能用调试器。我用加打印的方式调试。对于GUI程序,将打印输出送到另一个窗口就可以了。附录1介绍了我常用的GUI程序打印方法。
通过一步步增加打印,我发现问题是一个零结尾的字符串参数引起的。如果结尾零后面是非零值就不会错。如果结尾零后面还是零就会出错,这也就是直接运行Release版本时发生的情况。
发现问题原因后,我就可以用调试器了。调试Debug版本,在输入参数前断下来,将结尾零后面的数据改成0。然后就可以在调试器中跟踪运行。最后发现有一个函数没有判断字符串已经结束了,加个判断就好了。
2 bug2
bug2在调试中能出现就很容易调了。bug很简单:我有一个函数期待零结尾的C字符串。但我在一些调用的地方,传入字符串没有以零结尾,导致读数据越界。在Release版本,可能字符串后面有零字符,没有出现问题。在Debug版本,字符串后面很长一段都没有零字符,所以出现问题。
3 结束语
在VC调试中还有一个比较神奇的bug就是在调试状态弹出User breakpoint 的提示,我也碰到过几次。这是写越界,破坏堆数据引起的。解决方法可以见 “除虫记之十二:费解的NTDLL断点”。
其实不管有没有暴露出来,bug总是存在的,就像不管晴天雨天,太阳总是存在的。解决所有bug的最好方法还是在开发时再细心一些,不要让它们出现。
附录1 GUI程序的打印调试
我写过一个叫作MsgWin的小程序,它可以将WM_COPYDATA消息中的打印文本显示出来。在MsgWin中选择“工具”->“窗口名称”->“打印窗口”,将MsgWin的窗口名称设为“打印窗口”。然后在调试的程序中用FindWindow查找名称为“打印窗口”的窗口,将打印输出通过WM_COPYDATA消息发给它就可以了。
WM_COPYDATA消息的LPARAM参数的数据结构COPYDATASTRUCT定义如下:
typedef struct tagCOPYDATASTRUCT {
DWORD dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT, *PCOPYDATASTRUCT;
cbData是数据长度,单位是字节。lpData是数据指针。 WM_COPYDATA消息必须用SendMessage同步发送,所以指针指向的数据只要在调用SendMessage时有效就可以了。 MsgWin支持消息级别,也支持ANSI编码或Unicode编码的文本。这些信息都通过dwData传递:
- dwData小于10表示ANSI文本,dwData的值是消息级别;
- dwData大于或等于10表示Unicode文本,dwData-10的值是消息级别。
我整理了一个压缩包,包括MsgWin、MsgWin源程序和放在调试对象中的打印代码。打印代码有ANSI和UNICODE两个版本。
分享到:
相关推荐
通过结合使用这两个技术,你可以更轻松地诊断问题。 5. **代码审查与测试** 定期进行代码审查和编写单元测试也是确保代码质量的重要手段。通过同行评审,你可以发现潜在问题,而单元测试则确保每个函数或模块的...
《VC的调试技巧和方法》 在软件开发中,调试是一项至关重要的技能,尤其是在使用Visual C++(简称VC)这样的强大开发工具时。...因此,了解并实践这些调试方法,对于每个VC开发者来说都是必不可少的。
6. **创建工具栏**:此时,VC6.0会显示一个新的工具栏,包含两个图标。关闭此工具栏,退出并重启VC6.0。 7. **重新配置快捷键**:再次进入`Tools` -> `Customize` -> `Keyboard`,选择不同的类别,如`File`,`...
在VC++环境中,调试分为两种主要模式:Debug和Release。 1. 快速规范代码缩进格式:在VC++中,可以通过选中需要调整的代码,然后按Shift+F8来快速统一代码的缩进格式,这对于保持代码的整洁和易读性至关重要。 2. ...
2. **选择版本**:解压后的文件夹中有两个选项,VC6CN代表中文版,VC6EN代表英文版。根据个人语言需求,选择相应版本进行安装。 3. **启动安装**:进入选择的版本文件夹,找到安装图标并双击启动安装程序。 4-16. ...
如果这两个工具出现异常,可能需要更新或重新安装VC++环境。 - **MidlC.Exe**:这是一个特殊版本的MIDL编译器,可能针对特定的COM特性或优化。如果MidlC.Exe出错,可能是因为配置不当或文件损坏,需要检查编译路径...
本期刊聚焦于这两个领域的经典问题,旨在帮助程序员提升编程技能,解决实际开发中遇到的常见问题。 C语言,作为基础的系统编程语言,以其简洁、高效而被广泛使用。在C语言中,我们关注的重点包括内存管理、指针操作...
在这个场景下,这两个文件可能包含了修正VC6在64位环境下无法正常关闭的特定代码。 在实际操作中,用户需要先阅读替换说明,确保理解每一步操作,避免误操作导致的其他问题。通常,替换DLL文件需要备份原始文件,...
### VC编译调试 #### Debug和Release编译方式的本质区别 在软件开发过程中,程序员通常会面临选择不同的编译配置来构建他们的应用程序。最常见也是最重要的两种编译配置是Debug和Release模式。这两种模式的选择...
1. `configure.ac`和`Makefile.am`:这两个文件是用于自动构建系统的,通常在GNU项目中使用,帮助开发者配置和构建gloox库。 2. `AUTHORS`:列出库的主要贡献者和作者,对于了解库的开发背景和维护者很重要。 3. `...
首先,你需要根据你的操作系统选择相应的版本,压缩包中包含两个文件,分别是“VC6LineNumberAddin-32位”和“VC6LineNumberAddin-win7 64位”。如果你的系统是32位,那么你应该选择前一个文件;如果是64位系统,...
例如,在这个案例中,补丁被分为两个部分:`vc6sp6_1` 和 `vc6sp6_2`。用户需要先下载并安装第一部分,然后继续安装第二部分,以确保补丁完整安装。这是常见的大文件分段上传策略,旨在降低网络传输中的中断风险,并...
3. **DISPLAY.C 和 DISPLAYLIB.C**: 这两个文件可能是源代码文件,分别代表主程序和一个名为“DISPLAYLIB”的库。`.C` 文件通常包含C或C++的源代码,它们包含了程序的主要逻辑和函数定义。 4. **库文件**: `...
Release 版本和 Debug 版本是两个不同的版本,Release 版本称为发行版,Debug 版本称为调试版。Debug 版本中可以单步执行、跟踪等功能,但生成的可执行文件比较大,代码运行速度较慢。Release 版本运行速度较快,可...
同时,VC提供调试工具,帮助开发者查找和修复程序中的bug。 6. **源代码管理**:这个项目中包含了源代码,意味着可以查看和学习程序的内部实现。这对于初学者来说是很好的学习资源,他们可以通过阅读和分析代码,...
在开源项目中,通常会有不同的编译选项来调整程序的行为,例如优化级别、调试信息等。然而,"o111g"并不是标准的Apache标志,这可能是开发者或发行者自定义的标识,可能表示特定的优化级别或者针对某些环境的定制。 ...
总之,熟练掌握VC++的调试技术是每个C++开发者的必备技能。通过本教程的学习,你将能够更有效地诊断和修复程序中的错误,提升软件质量。记住,良好的调试习惯是优秀程序员的标志,持续学习和实践是提高的关键。
在Windows环境下,开发者可能经常需要对文件进行MD5校验,比如在下载大文件后确认其完整性,或者在比较两个文件是否完全相同时。`MD5KeyGen`这样的工具就提供了便利,用户只需提供文件路径,程序就会计算出该文件的...
9. **删除类**:彻底删除由ClassWizard生成的类,需先在FileView中选中类的`.h`和`.cpp`文件并删除,再在文件系统中删除这两个文件,最后运行ClassWizard并选择移除该类。 10. **找回丢失的类**:如果类在Workspace...
- 目前未实现的函数包括`HashPLL(char*)`和`PLL(void)`,这两个函数是第二套手法的最后一步,用于完成顶层的还原。 - 程序存在bug,可能会自动生成`.ml`文件记录错误状态,开发者鼓励用户提供这些文件以改进程序。...