Revision control

++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
++
++ /*!
++ \page debug.html
++ \title Debugging Techniques
++
++ Here we present some useful hints to help you with debugging your
++ Qt-based software.
++
++ \section1 Configuring Qt for Debugging
++
++ When \l{Qt Configure Options}{configuring} Qt for installation, it is possible
++ to ensure that it is built to include debug symbols that can make it
++ easier to track bugs in applications and libraries. However, on some
++ platforms, building Qt in debug mode will cause applications to be larger
++ than desirable.
++
++ \section2 Debugging in \macos and Xcode
++
++ \section3 Debugging With/Without Frameworks
++
++ The basic stuff you need to know about debug libraries and
++ frameworks is found at developer.apple.com in:
++ {Apple Technical Note TN2124}.
++
++ When you build Qt, frameworks are built by default, and inside the
++ framework you will find both a release and a debug version (e.g.,
++ QtCore and QtCore_debug). If you pass the \c{-no-framework} flag
++ when you build Qt, two dylibs are built for each Qt library (e.g.,
++ libQtCore.4.dylib and libQtCore_debug.4.dylib).
++
++ What happens when you link depends on whether you use frameworks
++ or not. We don't see a compelling reason to recommend one over the
++ other.
++
++ \section4 With Frameworks:
++
++ Since the release and debug libraries are inside the framework,
++ the app is simply linked against the framework. Then when you run
++ in the debugger, you will get either the release version or the
++ debug version, depending on whether you set \c{DYLD_IMAGE_SUFFIX}.
++ If you don't set it, you get the release version by default (i.e.,
++ non _debug). If you set \c{DYLD_IMAGE_SUFFIX=_debug}, you get the
++ debug version.
++
++ \section4 Without Frameworks:
++
++ When you tell \e{qmake} to generate a Makefile with the debug
++ config, it will link against the _debug version of the libraries
++ and generate debug symbols for the app. Running this program in
++ GDB will then work like running GDB on other platforms, and you
++ will be able to trace inside Qt.
++
++ \omit
++ Although it is not necessary to build Qt with debug symbols to use the
++ other techniques described in this document, certain features are only
++ available when Qt is configured for debugging.
++ \endomit
++
++ \section1 Command Line Options Recognized by Qt
++
++ When you run a Qt application, you can specify several
++ command-line options that can help with debugging. These are
++ recognized by QApplication.
++
++ \table
++ \header \li Option \li Description
++ \row \li \c -nograb
++ \li The application should never grab \link QWidget::grabMouse()
++ the mouse\endlink or \link QWidget::grabKeyboard() the
++ keyboard \endlink. This option is set by default when the
++ program is running in the \c gdb debugger under Linux.
++ \row \li \c -dograb
++ \li Ignore any implicit or explicit \c{-nograb}. \c -dograb wins over
++ \c -nograb even when \c -nograb is last on the command line.
++ \endtable
++
++ \section1 Environment Variables Recognized by Qt
++
++ At runtime, a Qt application recognizes many environment variables, some of which can
++ be helpful for debugging:
++
++ \table
++ \header \li Variable \li Description
++ \row \li \c QT_DEBUG_PLUGINS
++ \li Set to a non-zero value to make Qt print out diagnostic information about the each
++ (C++) plugin it tries to load.
++ \row \li \c QML_IMPORT_TRACE
++ \li Set to a non-zero value to make QML print out diagnostic information from the import
++ loading mechanism.
++ \row \li \c QT_HASH_SEED
++ \li Set to an integer value to disable QHash and QSet using a new random ordering for
++ each application run, which in some cases might make testing and debugging difficult.
++ \row \li \c QT_WIN_DEBUG_CONSOLE
++ \li On Windows, GUI applications are not attached to a console, so
++ output written to \c stdout and \c stderr is not visible to the
++ user. IDEs typically redirect and display output, but when running
++ an application from the command line, debug output is lost. To get
++ access to the output, set this environment variable to \c new to
++ make the application allocate a new console, or to \c attach to
++ make the application attempt to attach to the parent process'
++ console.
++ \endtable
++
++ \section1 Warning and Debugging Messages
++
++ Qt includes global C++ macros for writing out warning and debug text.
++ The plain macros use a default \l {QLoggingCategory}{logging category};
++ the categorized logging macros allow you to specify the category.
++ You can use them for the following purposes:
++
++ \table
++ \header \li Plain macro \li Categorized macro \li Purpose
++ \row \li qDebug()
++ \li qCDebug()
++ \li Used for writing custom debug output
++ \row \li qInfo()
++ \li qCInfo()
++ \li Used for informational messages
++ \row \li qWarning()
++ \li qCWarning()
++ \li Used to report warnings and recoverable errors in your application or library
++ \row \li qCritical()
++ \li qCCritical()
++ \li Used for writing critical error messages and reporting system errors
++ \row \li qFatal()
++ \li -
++ \li Used for writing messages about fatal errors shortly before exiting
++ \endtable
++
++ If you include the <QtDebug> header file, the \c qDebug() macro
++ can also be used as an output stream. For example:
++
++ \snippet snippets/code/doc_src_debug.cpp 0
++
++ The Qt implementation of these macros prints to the
++ \c stderr output under Unix/Linux and \macos. With Windows, if it
++ is a console application, the text is sent to console; otherwise, it
++ is sent to the debugger.
++
++ By default, only the message is printed. You can include additional information
++ by setting the \c QT_MESSAGE_PATTERN environment variable. For example:
++
++ \code
++ QT_MESSAGE_PATTERN="[%{time process} %{type}] %{appname} %{category} %{function} - %{message}"
++ \endcode
++
++ The format is documented in qSetMessagePattern(). You can also install your
++ own message handler using qInstallMessageHandler().
++
++ If the \c QT_FATAL_WARNINGS environment variable is set,
++ qWarning() exits after printing the warning message. This makes
++ it easy to obtain a backtrace in the debugger.
++
++ qDebug(), qInfo(), and qWarning() are debugging tools. They can be
++ compiled away by defining \c QT_NO_DEBUG_OUTPUT, \c
++ QT_NO_INFO_OUTPUT, or \c QT_NO_WARNING_OUTPUT during compilation.
++
++ The debugging functions QObject::dumpObjectTree() and
++ QObject::dumpObjectInfo() are often useful when an application
++ looks or acts strangely. More useful if you use \l{QObject::setObjectName()}{object names}
++ than not, but often useful even without names.
++
++ In QML, \l {QtQuick::Item::}{dumpItemTree()} serves the same purpose.
++
++ \section1 Providing Support for the qDebug() Stream Operator
++
++ You can implement the stream operator used by qDebug() to provide
++ debugging support for your classes. The class that implements the
++ stream is \c QDebug. Use \c QDebugStateSaver to temporarily
++ save the formatting options of the stream. Use
++ \l{QDebug::nospace()}{nospace()} and \l{QTextStream manipulators}
++ to further customize the formatting.
++
++ Here is an example for a class that represents a 2D coordinate.
++
++ \snippet snippets/qdebug/qdebugsnippet.cpp 0
++
++ Integration of custom types with Qt's meta-object system is covered
++ in more depth in the \l{Creating Custom Qt Types} document.
++
++ \section1 Debugging Macros
++
++ The header file \c <QtGlobal> contains some debugging macros and
++ \c{#define}s.
++
++ Three important macros are:
++ \list
++ \li \l{Q_ASSERT()}{Q_ASSERT}(cond), where \c cond is a boolean
++ expression, writes the warning "ASSERT: '\e{cond}' in file xyz.cpp, line
++ 234" and exits if \c cond is false.
++ \li \l{Q_ASSERT_X()}{Q_ASSERT_X}(cond, where, what), where \c cond is a
++ boolean expression, \c where a location, and \c what a message,
++ writes the warning: "ASSERT failure in \c{where}: '\c{what}', file xyz.cpp, line 234"
++ and exits if \c cond is false.
++ \li \l{Q_CHECK_PTR()}{Q_CHECK_PTR}(ptr), where \c ptr is a pointer.
++ Writes the warning "In file xyz.cpp, line 234: Out of memory" and
++ exits if \c ptr is 0.
++ \endlist
++
++ These macros are useful for detecting program errors, e.g. like this:
++
++ \snippet snippets/code/doc_src_debug.cpp 1
++
++ Q_ASSERT(), Q_ASSERT_X(), and Q_CHECK_PTR() expand to nothing if
++ \c QT_NO_DEBUG is defined during compilation. For this reason,
++ the arguments to these macro should not have any side-effects.
++ Here is an incorrect usage of Q_CHECK_PTR():
++
++ \snippet snippets/code/doc_src_debug.cpp 2
++
++ If this code is compiled with \c QT_NO_DEBUG defined, the code in
++ the Q_CHECK_PTR() expression is not executed and \e alloc returns
++ an uninitialized pointer.
++
++ The Qt library contains hundreds of internal checks that will
++ print warning messages when a programming error is detected. We
++ therefore recommend that you use a debug version of Qt when
++ developing Qt-based software.
++
++ Logging and \l {LoggingCategory}{categorized logging} are also
++ possible in \l {Debugging QML Applications}{QML}.
++
++ \section1 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 \link moc.html the meta-object compiler\endlink (\c{moc}),
++ but forget to link the \c{moc}-generated object code into your
++ executable, you will get very confusing error messages. Any link
++ error complaining about a lack of \c{vtbl}, \c{_vtbl}, \c{__vtbl}
++ or similar is likely to be a result of this problem.
++ */