C实例编程辅导(VC调试:两个有个性的bug)
来源:优易学  2011-11-25 12:22:44   【优易学:中国教育考试门户网】   资料下载   IT书店
  昨天在用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两个版本。

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训