Spec-Zone.ru › Qt 5.11

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

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

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

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

Отладка в macOS и Xcode

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

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

При построении Qt фреймворки создаются по умолчанию, и внутри фреймворка вы найдёте как релизную, так и отладочную версии (например, QtCore и QtCore_debug). Если вы передадите флаг -no-framework при построении Qt, для каждой Qt библиотеки (например, libQtCore.4.dylib и libQtCore_debug.4.dylib) будут построены две 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, where, what), где cond — булево выражение, where — местоположение, и what — сообщение, выводит предупреждение: «Ошибка ASSERT в 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/archives/qt-5.11/debug.html

Spec-Zone.ru

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