デバッグのテクニック
ここでは、Qt ベースのソフトウェアのデバッグに役立つヒントをいくつか紹介します。
デバッグ用の Qt の設定
Qt をインストール用に設定する際、アプリケーションやライブラリのバグ追跡を容易にするデバッグシンボルを含めてビルドするように指定することができます。ただし、一部のプラットフォームでは、Qt をデバッグモードでビルドすると、アプリケーションのサイズが望ましい範囲を超えてしまうことがあります。
macOS および Xcode でのデバッグ
フレームワークの有無によるデバッグ
デバッグ用ライブラリおよびフレームワークについて知っておくべき基本事項は、developer.apple.com の「Apple Technical Note TN2124」に記載されています。
Qtをビルドすると、デフォルトでフレームワークが生成され、そのフレームワーク内にはリリース版とデバッグ版の両方が含まれます(例:QtCore およびQtCore_debug)。 Qt のビルド時に `-no-framework ` フラグを指定すると、各 Qt ライブラリに対して 2 つの dylib がビルドされます(例:libQtCore.4.dylib および libQtCore_debug.4.dylib)。
リンク時の挙動は、フレームワークを使用するか否かによって異なります。どちらかを推奨する決定的な理由はありません。
フレームワークを使用する場合:
リリース版およびデバッグ版のライブラリがフレームワーク内に含まれているため、アプリケーションは単にそのフレームワークに対してリンクされます。その後、デバッガで実行する際、DYLD_IMAGE_SUFFIX の設定の有無に応じて、リリース版またはデバッグ版が実行されます。設定していない場合は、デフォルトでリリース版(つまり、_debug ではないもの)が実行されます。DYLD_IMAGE_SUFFIX=_debug を設定すると、デバッグ版が実行されます。
フレームワークを使用しない場合:
qmakeにデバッグ構成でMakefileを生成するよう指示すると、qmakeはライブラリの_debugバージョンに対してリンクを行い、アプリケーション用のデバッグシンボルを生成します。このプログラムをGDBで実行すると、他のプラットフォームでGDBを実行する場合と同様に動作し、Qt内部のトレースが可能になります。
Qtが認識するコマンドラインオプション
Qtアプリケーションを実行する際、デバッグに役立ついくつかのコマンドラインオプションを指定できます。これらはQApplication によって認識されます。
| オプション | 説明 |
|---|---|
-nograb | アプリケーションは、the mouse またはthe keyboard を絶対に取得してはなりません。このオプションは、Linux上のgdb デバッガでプログラムを実行する際、デフォルトで設定されます。 |
-dograb | 暗黙的または明示的な-nograb はすべて無視します。コマンドラインの最後に-nograb が指定されている場合でも、-dograb は-nograb より優先されます。 |
Qt が認識する環境変数
実行時、Qtアプリケーションは多くの環境変数を認識しますが、その中にはデバッグに役立つものもあります:
| 変数 | 説明 |
|---|---|
QT_DEBUG_PLUGINS | Qt が読み込もうとする各 (C++) プラグインに関する診断情報を出力させるには、この変数を 0 以外の値に設定します。 |
QML_IMPORT_TRACE | 0 以外の値に設定すると、QML がインポート読み込みメカニズムからの診断情報を出力するようになります。 |
QT_HASH_SEED | 整数値に設定すると、QHash およびQSet を無効にし、アプリケーションの実行ごとに新しいランダムな順序が使用されます。これにより、場合によってはテストやデバッグが困難になる可能性があります。 |
QT_WIN_DEBUG_CONSOLE | Windows では、GUI アプリケーションはコンソールにアタッチされないため、stdout およびstderr に出力された内容はユーザーには表示されません。IDE では通常、出力がリダイレクトされて表示されますが、コマンドラインからアプリケーションを実行すると、デバッグ出力は失われてしまいます。 出力にアクセスするには、この環境変数を `new ` に設定してアプリケーションに新しいコンソールを割り当てさせるか、`attach ` に設定してアプリケーションが親プロセスのコンソールに接続を試みるようにします。 |
警告およびデバッグメッセージ
Qtには、警告やデバッグテキストを出力するためのグローバルC++マクロが含まれています。プレーンなマクロはデフォルトでlogging category を使用します。カテゴリ分けされたロギングマクロを使用すると、カテゴリを指定できます。これらは以下の目的で使用できます:
| 単純なマクロ | カテゴリ別マクロ | 目的 |
|---|---|---|
| qDebug() | qCDebug() | カスタムデバッグ出力の記述に使用されます |
| qInfo() | qCInfo() | 情報メッセージに使用されます |
| qWarning() | qCWarning() | アプリケーションやライブラリにおける警告や回復可能なエラーを報告するために使用されます |
| qCritical() | qCCritical() | 重大なエラーメッセージの記述やシステムエラーの報告に使用されます |
| qFatal() | - | 終了直前に発生する致命的なエラーに関するメッセージの記述に使用されます |
<QtDebug> ヘッダーファイルをインクルードしている場合、qDebug() マクロを出力ストリームとして使用することもできます。例:
qDebug() << "Widget" << widget << "at position" << widget->pos();Unix/Linux および macOS では、これらのマクロの Qt 実装はstderr 出力に書き込みを行います。Windows の場合、コンソールアプリケーションであればテキストはコンソールに送信され、そうでない場合はデバッガーに送信されます。
デフォルトでは、メッセージのみが出力されます。QT_MESSAGE_PATTERN 環境変数を設定することで、追加情報を含めることができます。例:
QT_MESSAGE_PATTERN="[%{time process} %{type}] %{appname} %{category} %{function} - %{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()` は、アプリケーションの動作や表示に異常が見られる場合に役立ちます。object names を定義している場合はより有用ですが、名前を指定しなくても多くの場合役立ちます。
QML では、dumpItemTree() が同様の役割を果たします。
qDebug() ストリーム演算子のサポートの提供
qDebug() で使用されるストリーム演算子を実装することで、クラスに対するデバッグサポートを提供できます。このストリームを実装するクラスは `QDebug` です。QDebugStateSaver を使用して、ストリームの書式設定オプションを一時的に保存します。nospace() およびQTextStream manipulators を使用して、書式設定をさらにカスタマイズします。
以下に、2次元座標を表すクラスの例を示します。
QDebug operator<<(QDebug dbg, const Coordinate &c)
{
QDebugStateSaver saver(dbg);
dbg.nospace() << "(" << c.x() << ", " << c.y() << ")";
return dbg;
}カスタム型の Qt メタオブジェクトシステムへの統合については、「Creating Custom Qt Types」ドキュメントでより詳しく解説されています。
デバッグ用マクロ
ヘッダーファイル `<QtGlobal> ` には、いくつかのデバッグ用マクロおよび `#define` が含まれています。
重要なマクロは次の 3 つです。
- Q_ASSERT(cond) は、
condがブール式であり、condが false の場合、「ASSERT:'cond' in file xyz.cpp, line 234」という警告を出力して終了します。 - Q_ASSERT_X(cond, where, what):
condがブール式、whereが位置、whatがメッセージである場合、警告「ASSERT failure inwhere: 'what', file xyz.cpp, line 234」を出力し、condがfalseの場合はプログラムを終了します。 - Q_CHECK_PTR(ptr)、ここで
ptrはポインタである。ptrが 0 の場合、「ファイル xyz.cpp の 234 行目: メモリ不足」という警告を出力して終了する。
これらのマクロは、次のようなプログラムのエラー検出に役立ちます。
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のデバッグ版を使用することをお勧めします。
QML でも、ロギングや `categorized logging ` の使用が可能です。
QML では、ロギングや `xml-ph-0000@deepl.internal` も使用できます。
ここで特筆すべきほど一般的なバグが 1 つあります。クラス宣言に `Q_OBJECT ` マクロを含め、Meta-Object Compiler(moc) を実行したものの、moc によって生成されたオブジェクトコードを実行ファイルにリンクするのを忘れると、非常に分かりにくいエラーメッセージが表示されます。vtbl 、_vtbl 、__vtbl などのファイルが見つからないというリンクエラーは、この問題に起因している可能性が高いです。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.