Spec-Zone.ru › Qt

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

Здесь представлены некоторые полезные советы, которые помогут вам отладить ваше программное обеспечение на базе 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 — сообщение, выводит предупреждение: "Ошибка 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, __vtbl или подобного, вероятно, является результатом этой проблемы.

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

Spec-Zone.ru

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