主页 | 所有的类 | 主要的类 | 注释的类 | 分组的类 | 函数

调试技术

现在我们为您的基于Qt的软件的调试提供一些有用的提示。

命令行参数

当你运行Qt程序时,你可以指定几个命令行参数来帮助你调试。

警告和调试消息

Qt包含了三个全局函数来写出警告和调试文本。

这些函数的Qt实现是在Unix/X11下把文本打印到标准错误(stderr)输出,在Windows下会打印到调试器。你可以通过安装一个消息处理器,qInstallMsgHandler()来接收这些函数。

当应用程序看起来或者用起来很奇怪的时候,调试函数QObject::dumpObjectTree()和QObject::dumpObjectInfo()很有用。如果你使用了对象名称,这将会更有用,但通常情况下是没有名称的。

调试宏

qglobal.h头文件包含了很多调试宏和#defines。

两个重要的宏是:

这些宏在检测程序错误时很有用,比如像这样:

  char *alloc( int size )
  {
      Q_ASSERT( size > 0 );
      char *p = new char[size];
      Q_CHECK_PTR( p );
      return p;
  }

如果你定义了QT_FATAL_ASSERT标记,Q_ASSERT将会调用fatal()而不是warning(),所以一个错误声明将会导致在打印错误消息后使程序退出。

注意如果QT_CHECK_STATE未定义,Q_ASSERT宏就是一个空的表达式(参见下面)。在里面的任何代码都不会被执行。相似的,如果QT_CHECK_NULL未定义,Q_CHECK_PTR也是一个空的表达式。这里就是一个应该如此使用Q_ASSERT和Q_CHECK_PTR的例子:

  char *alloc( int size )
  {
      char *p;
      Q_CHECK_PTR( p = new char[size] ); // WRONG
      return p;
  }

这个问题是棘手的:仅仅在正确的检测标记被定义时,p才会被设置为健全的值。如果QT_CHECK_NULL标记没有被定义,代码被编译了,在Q_CHECK_PTR表达式中的代码是不会被执行的(正确地,因为它仅仅用于调试目的)并且会分配一个疯狂的指针。

Qt库包含了几百个内部检查,当一些错误被检测出时,会打印警告信息。

Qt中的健全测试和作为结果的警告信息是有条件的,基于不同的调试标记的状态:

默认情况下,QT_DEBUG和所有的QT_CHECK标记都是打开的。如果要关闭QT_DEBUG,请定义QT_NO_DEBUG。如果要关闭QT_CHECK标记,请定义QT_NO_CHECK。

实例:

  void f( char *p, int i )
  {
  #if defined(QT_CHECK_NULL)
      if ( p == 0 )
          qWarning( "f: Null pointer not allowed" );
  #endif

  #if defined(QT_CHECK_RANGE)
      if ( i < 0 )
          qWarning( "f: The index cannot be negative" );
  #endif
  }

普通的Bug

这是一个如此普通的bug,所以要在这里提到:如果你你在类生命中包含了Q_OBJECT宏并且运行了moc,但是忘记了把moc生成的对象代码连接到你的可执行程序中,你就会得到非常困惑的错误消息。

任何一个会提示缺乏vtbl_vtbl__vtbl或者和这个类似的连接错误都有可能是这样的问题。


Copyright © 2002 Trolltech Trademarks 译者:Cavendish
Qt 3.0.5版