Spec-Zone.ru › Qt 5.14

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

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

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

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

Отладка в macOS и Xcode

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

Основные сведения об отладочных библиотеках и фреймворках можно найти на сайте developer.apple.com в: Технической заметке Apple 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 с отладочной конфигурацией, он будет линковаться с _debug версией библиотек и генерировать символы отладки для приложения. Запуск этой программы в 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 — сообщение, выводит предупреждение: «Ошибка проверки в 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-5.14/debug.html

Spec-Zone.ru

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