Home | All Classes | Main Classes | Annotated | Grouped Classes | Functions |

# Debugging Techniques

Here we present some useful hints to debugging your Qt-based software.

## Command Line Options

When you run a Qt program you can specify several command line options that can help with debugging.

Option | Result
--- | ---
-nograb | The application should never grab the mouse or the keyboard. This option is set by default when the program is running in the `gdb` debugger under Linux.
-dograb | Ignore any implicit or explicit -nograb. -dograb wins over -nograb even when -nograb is last on the command line.
-sync | Runs the application in X synchronous mode. Synchronous mode forces the X server to perform each X client request immediately and not use buffer optimization. It makes the program easier to debug and often much slower. The -sync option is only valid for the X11 version of Qt.

## Warning and Debugging Messages

Qt includes four global functions for writing out warning and debug text.

- qDebug() for writing debug output for testing etc.
- qWarning() for writing warning output when program errors occur.
- qSystemWarning() for writing warning output when system errors occur. The output is completed by the system's last error message (if available).
- qFatal() for writing fatal error messages and exiting.

The Qt implementation of these functions prints the text to the `stderr` output under Unix/X11 and to the debugger under Windows. You can take over these functions by installing a message handler; qInstallMsgHandler().

If the environment variable `QT_FATAL_WARNINGS` is defined, qWarning() exits after printing the warning message. This makes it possible to easily locate errors in a debugger.

Note that qDebug() and qWarning() are debugging tools only, they do nothing if `QT_NO_DEBUG` was defined during compilation; whereas qSystemWarning() and qFatal() also apply in release mode.

The debugging functions QObject::dumpObjectTree() and QObject::dumpObjectInfo() are often useful when an application looks or acts strangely. More useful if you use object names than not, but often useful even without names.

## Debugging Macros

The header file `qglobal.h` contains some debugging macros and `#define`s.

Three important macros are:

- Q_ASSERT(b) where b is a boolean expression, writes the warning: "ASSERT: 'b"' in file file.cpp, line 234" and exits if b is false.
- Q_ASSERT_X(b, where, what) where b is a boolean expression, where a location and what a message, writes the warning: "ASSERTfailure in where: 'what', file file.cpp, line 234" and exits if b is false.
- Q_CHECK_PTR(p) where p is a pointer. Writes the warning "In file file.cpp, line 234: Out of memory" and exits if p is 0.

These macros are useful for detecting program errors, e.g. like this:

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

Note that Q_ASSERT, Q_ASSERT_X and Q_CHECK_PTR are null expressions if `QT_NO_DEBUG` was defined during compilation. Any code in them will simply not be executed. Here is an example of how you should not use Q_ASSERT and Q_CHECK_PTR:

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

The problem is tricky: p is set to a sane value only as long as the correct checking flags are defined. If this code is compiled with the QT_NO_DEBUG flag defined, the code in the Q_CHECK_PTR expression is not executed (correctly, since it's only a debugging aid) and alloc returns a wild pointer.

The Qt library contains hundreds of internal checks that will print warning messages when some error is detected. We thus recommend using a debug build of Qt when developing Qt-based software.

## Common bugs

There is one bug that is so common that it deserves mention here: If you include the Q_OBJECT macro in a class declaration and run the moc, but forget to link the moc-generated object code into your executable, you will get very confusing error messages. Any link error complaining about a lack of `vtbl`, `_vtbl`, `__vtbl` or similar is likely to be a result of this problem.