posts - 319, comments - 22, trackbacks - 0, articles - 11
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

QT调试技术

Posted on 2011-06-01 21:46 RTY 阅读(530) 评论(0)  编辑 收藏 引用 所属分类: Qt转载随笔
在这里我们提及一些Qt程序的调试的使用.
一、命令行选项
当你运行Qt程序的的时候你可以指定几个命令行选项来帮助程序的调试.
-nograb 应用程序不会抢夺鼠标和键盘. 当程序运行在Linux下的gdb调试工具下的时候,这个值是默认设置的.
-dograb 忽略任何暗示的或明示的-nograb. 即使-nograb放在命令行的最后时,-dograb也胜于-nograb的调用,即-dograb的优先级更高.
-sync 应用程序在X的同步模式下运行. 同步模式强制X服务器立即执行每个X客户端的请求并且不使用缓冲区(buffer)的优化. 它使程序更便于调试,但是速度更慢.-sync选项仅在Qt的X11版本上有效.
二、警告和调试信息
Qt的拥有本个全局函数来输出警告及调试文本.
qDebug() 用于测试等的调试信息的输出.
qWarning() 用于当程序出现错误的时候的警告信息的输出.
qFatal() 用于毁灭性的错误信息的输出及程序的退出.
Qt 通过这些函数的执行将信息传给Unix/X11下的stderr output或传给Windows下的调试器. 你可以通过qInstallMsgHandler()安装信息句柄(message handler)来接管这些函数.
当一个应用程序很奇怪地运行时,调试函数QObject::dumpObjectTree() 和QObject::dumpObjectInfo() 是很有用的. 用对象名比不用对象名更有帮助,虽然有的时候不用名称都是那么有帮助.
三、调试宏
头文件qglobal.h包含了许多的调试宏及其定义.
两个重要的宏:
ASSERT(b) 其中b 是一个布尔表达式, 如果b的FALSE,将会输出警告信息: "ASSERT: 'b' in file file.cpp (234)" ---->表示在文件file.cpp的第234行中b的值为FALSE. 
CHECK_PTR(p) 其中p 是一个指针. 当p为空的时候将会输出警告信息: "In file file.cpp, line 234: Out of memory" ---->表示在文件file.cpp的第234行,内存溢出. 
这些宏在检测程序错误时是非常有用的, 比如说:
  char *alloc( int size )
  {
      ASSERT( size > 0 );
      char *p = new char[size];
      CHECK_PTR( p );
      return p;
  }
如果你定义了标志QT_FATAL_ASSERT, ASSERT将会调用fatal()取代warning(), 所以一个失败的断言将会导致程序在输出错误信息后退出.
注意:如果CHECK_STATE(下面会讲到)没有定义的话,那么ASSERT宏是一个空的表达式. 在它里头的代码将不会被执行. 同样的,如果CHECK_NULL没有定变色镜的话,CHECK_PTR也是一个空的表达式. 这里是一个怎样让ASSERT 或CHECK_PTR成为NOT的例子:
  char *alloc( int size )
  {
      char *p;
      CHECK_PTR( p = new char[size] );  // never do this!
      return p;
  }
这个程序的繁杂的:只有在正确检测试标志被定义的时候, p 才会被设为一个稳当的值. 如果这个代码没有定义CHECK_NULL标志, 那么在CHECK_PTR表达式里的代码将不会执行(一般地,它只是帮助调试) 并返回一个野指指.
Qt库包含了几百条内在的检测,当有一些错误被检测出来之后,将会输出警告信息.
基于下列不同调试标志的状态,可以进行对Qt内部的完整性和结果的正确性的测试:
CHECK_STATE: 检查对象的状态的一致性.Check for consistent/expected object state 
CHECK_RANGE: 检查变量的范围错误. 
CHECK_NULL: 检查危险的空指针.
CHECK_MATH: 检查危险的数学运算, 比如说除以0的运算. 
NO_CHECK: 关闭所有的CHECK_... 标志 .
DEBUG: 允许使用调试代码.
NO_DEBUG: 关闭 DEBUG 标志. 
默认情况下, DEBUG和所有的CHECK 标志都是打开的. 要关闭 DEBUG, 定义NO_DEBUG. 要关闭CHECK标志,定义 NO_CHECK.
例:
  void f( char *p, int i )
  {
  #if defined(CHECK_NULL)
      if ( p == 0 )
          qWarning( "f: Null pointer not allowed" );
  #endif
  #if defined(CHECK_RANGE)
      if ( i < 0 )
          qWarning( "f: The index cannot be negative" );
  #endif
  }
四、一般的bugs
这里我们值得提及的一个公共的BUG: 如果你包含了一个Q_OBJECT宏在类的声明和运行moc的时候, 并且又忘了链接到moc生成对象代码到你的可执行程序上,那么你将会得到一些非常模糊的错误信息. 
任何链接错误信息都是关于vtbl, _vtbl, __vtbl 或类似于这样一类问题缺乏的提示信息. 

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理