Spec-Zone.ru › Qt 5.12

Методы отладки

Здесь представлены некоторые полезные подсказки, которые помогут вам отладить ваше программное обеспечение на базе Qt.

Настройка Qt для отладки

При настройке Qt для установки можно убедиться, что он скомпилирован с включением отладочных символов, что облегчает отслеживание ошибок в приложениях и библиотеках. Однако на некоторых платформах компиляция Qt в отладочном режиме приведет к увеличению размера приложений, что может быть нежелательно.

Отладка в macOS и Xcode

Отладка с/без фреймворков

Основные сведения об отладочных библиотеках и фреймворках можно найти на сайте developer.apple.com: Apple Technical Note TN2124.

При компиляции Qt фреймворки создаются по умолчанию, и внутри фреймворка вы найдете как релизную, так и отладочную версии (например, QtCore и QtCore_debug). Если вы передаете флаг -no-framework при компиляции Qt, для каждой библиотеки Qt создаются две dylib (например, libQtCore.4.dylib и libQtCore_debug.4.dylib).

То, что произойдет при линковке, зависит от того, используете ли вы фреймворки или нет. Мы не видим веских причин рекомендовать один вариант вместо другого.

С фреймворками:

Поскольку релизные и отладочные библиотеки находятся внутри фреймворка, приложение просто подключается к фреймворку. Затем, при запуске в отладчике, вы получите либо релизную, либо отладочную версию, в зависимости от того, установили ли вы DYLD_IMAGE_SUFFIX. Если вы этого не сделаете, по умолчанию используется релизная версия (то есть без _debug). Если вы установите DYLD_IMAGE_SUFFIX=_debug, вы получите отладочную версию.

Без фреймворков:

Когда вы указываете qmake сгенерировать Makefile с отладочной конфигурацией, он будет подключаться к отладочной версии библиотек и генерировать отладочные символы для приложения. Запуск этой программы в GDB будет работать так же, как и на других платформах, и вы сможете отслеживать внутренние процессы Qt.

Командные строки, распознаваемые Qt

При запуске приложения Qt вы можете указать несколько командных строк, которые могут помочь в отладке. Они распознаются QApplication.

Опция Описание
-nograb Приложение никогда не должно захватывать мышь или клавиатуру. Этот параметр устанавливается по умолчанию, когда программа запускается в gdb отладчике под Linux.
-dograb Игнорировать все неявные или явные -nograb. -dograb имеет приоритет над -nograb, даже когда -nograb указано в последнюю очередь в командной строке.

Переменные окружения, распознаваемые Qt

Во время выполнения приложение Qt распознает множество переменных окружения, некоторые из которых могут быть полезны для отладки:

Переменная Описание
QT_DEBUG_PLUGINS Установите значение, отличное от нуля, чтобы Qt печатал диагностическую информацию о каждом (C++) плагине, который он пытается загрузить.
QML_IMPORT_TRACE Установите значение, отличное от нуля, чтобы QML печатал диагностическую информацию из механизма загрузки импорта.
QT_HASH_SEED Установите целочисленное значение, чтобы отключить QHash и QSet, используя новую случайную упорядоченность для каждого запуска приложения, что в некоторых случаях может затруднить тестирование и отладку.

Сообщения об ошибках и отладки

Qt включает глобальные макросы для вывода сообщений об ошибках и отладки. Вы можете использовать их для следующих целей:

  • qDebug() используется для вывода пользовательских отладочных данных.
  • qInfo() используется для информационных сообщений.
  • qWarning() используется для сообщения об ошибках и восстанавливаемых ошибках в вашем приложении.
  • qCritical() используется для вывода критических сообщений об ошибках и сообщения об ошибках системы.
  • qFatal() используется для вывода фатальных сообщений об ошибках незадолго до завершения работы.

Если вы включите заголовочный файл <QtDebug>, макрос qDebug() также может использоваться как поток вывода. Например:

qDebug() << "Widget" << widget << "at position" << widget->pos();

Реализация Qt этих макросов печатает в поток stderr под Unix/X11 и macOS. В Windows, если это консольное приложение, текст отправляется в консоль; в противном случае он отправляется в отладчик.

По умолчанию печатается только сообщение. Вы можете включить дополнительную информацию, установив переменную окружения QT_MESSAGE_PATTERN. Например:

QT_MESSAGE_PATTERN="[%{type}] %{appname} (%{file}:%{line}) - %{message}"

Формат описан в qSetMessagePattern(). Вы также можете установить свой собственный обработчик сообщений с помощью qInstallMessageHandler().

Если переменная окружения QT_FATAL_WARNINGS установлена, qWarning() завершает работу после вывода сообщения об ошибке. Это упрощает получение трассировки стека в отладчике.

qDebug(), qInfo() и qWarning() являются средствами отладки. Их можно исключить, определив QT_NO_DEBUG_OUTPUT, QT_NO_INFO_OUTPUT, или QT_NO_WARNING_OUTPUT во время компиляции.

Функции отладки QObject::dumpObjectTree() и QObject::dumpObjectInfo() часто полезны, когда приложение ведет себя или выглядит странно. Они полезнее, если вы используете имена объектов, но часто полезны и без них.

Обеспечение поддержки оператора потока qDebug()

Вы можете реализовать оператор потока, используемый qDebug(), чтобы обеспечить поддержку отладки для ваших классов. Класс, который реализует оператор потока, — QDebug. Используйте QDebugStateSaver для временного сохранения параметров форматирования потока. Используйте nospace() и манипуляторы QTextStream для дальнейшей настройки форматирования.

Вот пример класса, представляющего 2D координаты.

QDebug operator<<(QDebug dbg, const Coordinate &c)
{
    QDebugStateSaver saver(dbg);
    dbg.nospace() << "(" << c.x() << ", " << c.y() << ")";

    return dbg;
}

Интеграция пользовательских типов с метаобъектной системой Qt более подробно рассмотрена в документе Создание пользовательских типов Qt.

Макросы отладки

Заголовочный файл <QtGlobal> содержит некоторые макросы отладки и #define.

Три важных макроса:

  • Q_ASSERT(cond), где cond — булево выражение, выводит предупреждение "ASSERT: 'cond' в файле xyz.cpp, строка 234" и завершает работу, если cond ложно.
  • Q_ASSERT_X(cond, где, что), где cond — булево выражение, where — местоположение, и what — сообщение, выводит предупреждение: "Ошибка утверждения в where: 'what', файл xyz.cpp, строка 234" и завершает работу, если cond ложно.
  • Q_CHECK_PTR(ptr), где ptr — указатель. Выводит предупреждение "В файле xyz.cpp, строка 234: Недостаточно памяти" и завершает работу, если ptr равен 0.

Эти макросы полезны для обнаружения ошибок программы, например, так:

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

Q_ASSERT(), Q_ASSERT_X() и Q_CHECK_PTR() расширяются до ничего, если QT_NO_DEBUG определено во время компиляции. По этой причине аргументы этих макросов не должны иметь побочных эффектов. Вот неправильное использование Q_CHECK_PTR():

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

Если этот код скомпилирован с определенным QT_NO_DEBUG, код в выражении Q_CHECK_PTR() не выполняется, и alloc возвращает неинициализированный указатель.

Библиотека Qt содержит сотни внутренних проверок, которые будут выводить сообщения об ошибках, когда будет обнаружена ошибка программирования. Поэтому мы рекомендуем использовать отладочную версию Qt при разработке программного обеспечения на базе Qt.

Распространенные ошибки

Существует одна ошибка, настолько распространенная, что заслуживает упоминания здесь: если вы включаете макрос Q_OBJECT в объявлении класса и запускаете компилятор метаобъектов (moc), но забываете подключить сгенерированный метаобъектом код в исполняемый файл, вы получите очень запутанные сообщения об ошибках. Любая ошибка линковки, жалующаяся на отсутствие moc, vtbl, _vtbl или подобного, скорее всего, является результатом этой проблемы.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.12/debug.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API