デバッグヘルパー
Qt Creator は、Pythonスクリプトを使用して、デバッガーバックエンド(GDB、LLDB、およびCDBが現在サポートされています)からの生のメモリコンテンツと型情報データを、LocalsおよびExpressionsビューでユーザーに表示される形式に変換します。
GDB のプリティプリンターや LLDB のデータフォーマッターとは異なり、Qt Creator のデバッグヘルパーはネイティブのデバッグバックエンドとは独立しています。つまり、同じコードをLinuxのGDB、macOSのLLDB、WindowsのCDB、またはサポートされている3つのバックエンドの少なくとも1つが利用可能な他のプラットフォームで使用することができます。
システムにインストールされている、またはアプリケーションが使用するライブラリにリンクされているデフォルトのGDBプリティプリンタを使用するには、Preferences>Debugger >GDB >Load system GDB pretty printers にアクセスしてください。詳細については、GDB を参照してください。

組み込みデバッグ・ヘルパーのカスタマイズ
組み込みのデバッグ・ヘルパーがロードされ、完全に初期化された後にコマンドを実行させることができます。追加のデバッグ・ヘルパーをロードしたり、既存のヘルパーを変更したりするには、Preferences>Debugger >Locals & Expressions に進み、Debugging Helper Customization フィールドにコマンドを入力します。

GDB使用時にシグナル受信に関するエラーメッセージが表示される場合は、シグナ ルを処理するためのGDBコマンドを指定できます。例えば、次のようなエラー・メッセージが表示された場合、SIGSTOP シグナルを無視するように GDB に指示できます:The debugged process stopped because it received a signal from the operating system. Signal name: SIGSTOP.
GDB がSIGSTOP シグナルを処理しないようにするには、Debugging Helper Customization フィールドに以下のコマンドを追加します:
handle SIGSTOP nopass handle SIGSTOP nostop
デバッグ中にアプリケーションがシグナルを受信するとすぐにメッセージ・ ボックスを表示するには、Preferences>Debugger >GDB >Show a message box when receiving a signal.
カスタム・デバッグ・ヘルパーの追加
独自の型のデバッグ・ヘルパーを追加するには、コンパイルは不要で、Pythonを数行追加するだけです。スクリプトは、複数のバージョンの Qt や独自のライブラリを同時に扱うことができます。
カスタム型用のデバッグヘルパーを追加するには、デバッガーのスタートアップファイル(例えば、~/.gdbinit や~/.lldbinit )にデバッグヘルパーの実装を追加するか、Additional Startup Commands の環境設定>Debugger >GDB で直接指定します。
独自のデータ型用のデバッグヘルパーの実装を始めるには、Qt インストールまたはスタンドアロンQt Creator インストールのファイルshare/qtcreator/debugger/personaltypes.py にその実装を記述します。macOSでは、このファイルはQt Creator アプリケーションパッケージにバンドルされており、Contents/resources/debugger フォルダにあります。
personaltypes.py ファイルには実装例が1つあります:
# def qdump__MapNode(d, value):
# d.putValue("This is the value column contents")
# d.putExpandable()
# if d.isExpanded():
# with Children(d):
# # Compact simple case.
# d.putSubItem("key", value["key"])
# # Same effect, with more customization possibilities.
# with SubItem(d, "data")
# d.putItem("data", value["data"])デバッグ・ヘルパーを追加する:
share/qtcreator/debugger/personaltypes.pyファイルを開いて編集します。例えば、Qt のインストールが Windows のQt5ディレクトリにある場合、C:\Qt5\Tools\QtCreator\share\qtcreator\debuggerを見てください。macOSではQt5/Qt Creator.app/Contents/resources/debugger.- ダンパーの実装を
personaltypes.pyファイルの最後に追加します。デバッグヘルパーの実装についての詳細は、以下のセクションを参照してください。 - Qt Creator を更新したとき(Qt を更新したときなど)に
personaltypes.pyが上書きされないようにするには、ファイルシステム内のQt Creator 以外の安全な場所にコピーし、Preferences>Debugger >Locals & Expressions >Extra Debugging Helper でその場所を指定してください。
カスタムデバッギングヘルパーは、Qt Creator でデバッグセッションを開始するか、デバッガーログビューのコンテキストメニューからReload Debugging Helpers を選択すると、personaltypes.py から自動的にピックアップされます。
デバッグヘルパーの概要
デバッグヘルパーの実装は通常、1 つの Python 関数で構成され、qdump__NS__Foo という名前が必要です。NS::Foo は検査するクラスまたはクラステンプレートです。:: のスコープ解決演算子はダブルアンダースコアに置き換えられることに注意してください:__ 。名前空間の入れ子は可能です。テンプレート引数は、関数名の作成には使用されません。
例
namespace Project { template<typename T> struct Foo {... } }型のデバッグ・ヘルパーを実装する関数の名前はqdump__Project__Fooです。std::__1::vector<T>::iterator型のデバッグ・ヘルパーを実装する関数の名前はqdump__std____1__vector__iteratorです。
Qt Creatorデバッガ・プラグインは、この型のオブジェクトを表示したいときにこの関数を呼び出します。この関数には以下のパラメータが渡されます:
d型のDumper、現在の設定を持ち、Locals とExpressions のビューの一部を表すオブジェクトを構築する機能を提供するオブジェクト。valueValue型の、gdb.Valueまたはlldb.SBValue をラップしたオブジェクト。
qdump__* 関数は、Locals とExpressions のビューでオブジェクトとその子の表示を構築するために使用される特定の情報をDumperオブジェクトに供給する必要があります。
例
def qdump__QFiniteStack(d, value): alloc = value["_alloc"].integer() size = value["_size"].integer() d.putItemCount(size) if d.isExpanded(): d.putArrayData(value["_array"], size, value.type[0])
注意: LLDBとGDBの両方のバックエンドで使用可能なダンパ関数を作成するには、gdb.* とlldb.* 名前空間への直接アクセスを避け、代わりにDumper クラスの関数を使用してください。
デバッグ・ヘルパーでオブジェクトのベース・インスタンスにアクセスするには、value.base() 関数または以下のサンプル・コードを使用してください:
def qdump__A(d, value): t = value.members(True)[0].type dptr, base_v = value.split('p{%s}' % t.name) d.putItem(base_v)
デバッグヘルパーは、型名が正規表現にマッチするたびに呼び出されるように設定できます。そのためには、デバッグヘルパーの関数名はqdump__ (アンダースコア2文字)で始まる必要があります。さらに、この関数には、型名がマッチする正規表現を指定するデフォルト値のregex という3番目のパラメータが必要です。
例えば、Nim 0.12コンパイラーは、コンパイルするすべてのジェネリック・シーケンスに、TY1 やTY2 のような人工的な名前を割り当てます。これらをQt Creator で視覚化するために、以下のデバッグ・ヘルパーを使用することができます:
def qdump__NimGenericSequence__(d, value, regex = "^TY.*$"): size = value["Sup"]["len"] base = value["data"].dereference() typeobj = base.dereference().type d.putArrayData(base, size, typeobj)
デバッグ・ヘルパーの実装
デバッグヘルパーは、GDB/MIとJSONに似たフォーマットで、表示されたデータ項目の説明を作成する。
Locals およびExpressions ビューの各行について、以下のような文字列を作成し、デバッガープラグインにチャネリングする必要があります。
{ iname='some internal name', # optional
address='object address in memory', # optional
name='contents of the name column', # optional
value='contents of the value column',
type='contents of the type column',
numchild='number of children', # zero/nonzero is sufficient
children=[ # only needed if item is expanded in view
{iname='internal name of first child',
},
{iname='internal name of second child',
},
]}iname フィールドの値はオブジェクトの内部名で、ドット区切りの識別子リストで構成され、ビュー内のオブジェクトの表現位置に対応しています。存在しない場合は、親オブジェクトのiname 、ドット、連番を連結して生成される。
name フィールドの値は、ビューのName 列に表示されます。指定されない場合、代わりに括弧内の単純な数値が使用されます。
フォーマットの安定性は保証されていませんので、ワイヤーフォーマットを直接生成するのではなく、Python Dumperクラスの抽象化レイヤー、特にDumper クラス自身とDumper:Value 、Dumper:Type 抽象化レイヤーを使用することを強く推奨します。これらは、iname とaddr フィールドを処理し、単純な型の子、参照、ポインタ、列挙型、既知および未知の構造体を処理するための完全なフレームワークと、一般的な状況を処理するためのいくつかの便利な関数を提供します。
CDBをデバッガーのバックエンドとして使用する場合、Preferences>Debugger >CDB >Use Python dumper を選択することで、Pythonダンパを有効にすることができます。

以下のセクションでは、qtcreator\share\qtcreator\debugger\dumper.py で指定されている、広く使用されているDumperクラスとメンバについて説明します。
Dumperクラス
Dumper クラスは一般的な簿記、低レベル関数、便利関数を持っています:
putItem(self, value)- マスタ関数は、基本型、参照、ポインタ、列挙型を直接処理し、複合型の基底クラスとクラス・メンバを繰り返し処理し、必要に応じてqdump__*関数を呼び出します。putIntItem(self, name, value)- と同等:with SubItem(self, name): self.putValue(value) self.putType("int")
putBoolItem(self, name, value)- と同等:with SubItem(self, name): self.putValue(value) self.putType("bool")
putCallItem(self, name, rettype, value, func, *args)- デバッガ・バックエンドを使用して、value で指定された値にrettypeを返す関数呼び出しfuncを配置し、結果の項目を出力します。ネイティブ呼び出しは非常に強力で、たとえばデバッグ対象プロセスで既存のデバッグまたはロギング機能を活用できます。しかし、以下の理由により、ネイティブ・コールは制御された環境でのみ、またデータにアクセスする他の方法がない場合にのみ使用する必要があります:
- コードの直接実行は危険である。コードの直接実行は危険であり、デバッグ対象プロセスの特権でネイティブ・コードを実行し、デバッグ対象プロセスを破壊するだけでなく、ディスクやネットワークにアクセスする可能性がある。
- コアファイルの検査時にコールを実行することはできない。
- コールは、デバッガーでのセットアップと実行にコストがかかります。
putArrayData(self, address, itemCount, type)-addressにある配列のようなオブジェクトの型typeのitemCountで指定された数の子を作成します。putSubItem(self, component, value)- に相当する:with SubItem(self, component): self.putItem(value)
ネストされた関数呼び出しによって発生した例外はキャッチされ、
putItemによって生成されたすべての出力は、その出力に置き換えられます:except RuntimeError: d.put('value="<invalid>",type="<unknown>",numchild="0",')put(self, value)- 出力文字列に直接追加する低レベル関数。これは出力を追加する最速の方法でもある。putField(self, name, value)-name='value'フィールドを追加する。childRange(self)- 現在のChildrenスコープで指定された子の範囲を返します。putItemCount(self, count)-value='<%d items>'フィールドを出力に追加します。putName(self, name)-name=''フィールドを追加する。putType(self, type, priority=0)-type が親のデフォルトの子型と一致するか、putTypeが現在の項目に対してより高い値priorityで既に呼び出されていない限り、type=''フィールドを追加します。putBetterType(self, type)- 最後に記録されたtypeを上書きする。putExpandable(self)- 現在の値に対する子項目の存在を通知します。デフォルトは子項目なしです。putNumChild(self, numchild)- 現在の値に対する子項目の存在 (numchild> 0) または非存在を通知します。putValue(self, value, encoding = None)- ファイルvalue=''を追加し、オプションでその後にフィールドvalueencoding=''を追加する。valueは、すべて英数字からなる文字列に変換できる必要がある。英数字のみの要件を満たすために、実際の値を何らかの方法でエンコードする必要があった場合に備えて、encodingパラメータを使用してエンコードを指定することができる。パラメータencodingは、codec:itemsize:quote形式の文字列で、codecは、latin1、utf8、utf16、ucs4、int、floatのいずれかである。itemsizeは、codecによって暗示されていない場合、オブジェクトの基本コンポーネントのサイズを与え、quoteは、値を引用符で囲んで表示するかどうかを指定する。例
# Safe transport of quirky data. Put quotes around the result. d.putValue(d.hexencode("ABC\"DEF"), "utf8:1:1")
putStringValue(self, value)- 例:QString をエンコードし、正しいencoding設定でputValueを呼び出す。putByteArrayValue(self, value)-QByteArray をエンコードし、正しいencoding設定でputValueを呼び出す。isExpanded(self)- 現在のアイテムがビューで展開されているかどうかをチェックします。createType(self, pattern, size = None)-Dumper.Typeオブジェクトを作成します。正確な操作はpatternに依存します。patternがよく知られた型の名前と一致する場合、この型を記述したDumper.Typeオブジェクトが返されます。patternがネイティブ・バックエンドで既知の型の名前である場合、返される型はネイティブ型を記述します。- そうでない場合、
patternは、構造体のフィールドを記述する一連の項目を以下のように解釈して型記述を構築するために使用される。フィールド記述は、以下のように1文字以上で構成される:q- 符号付き8バイト整数値Q- 符号なし8バイト整数値i- 符号付き4バイト整数値I- 符号なし4バイト整数値h- 符号付き 2 バイト積分値H- 符号なし2バイト積分値b- 符号あり1バイト積分値B- 符号なし1バイト積分値d- 8バイトIEEE 754浮動小数点値f- 4バイトIEEE 754浮動小数点値p- ポインタ、つまりターゲット・アーキテクチャに応じた適切なサイズの符号なし積分値。@- 適切なパディング。サイズは前後のフィールドとターゲット・アーキテクチャによって決定される。<n>s- <n>バイトのブロブ、暗黙のアライメントは1。<typename>Dumper.Type- 適切なサイズと適切なアラインメントを持つブロブ。typename
Dumper.Typeクラス
Dumper.Type 。このクラスは、データ(通常はC++のクラスや構造体、構造体へのポインタ、または積分型や浮動小数点型などのプリミティブ型)の型を記述します。
型オブジェクト、つまりDumper.Type クラスのインスタンスは、デバッガー・バックエンドによって作成できます。通常は、デバッグ・バイナリに組み込まれているか、デバッグ・バイナリとともに出荷されているデバッグ情報を評価するか、デバッグ・ヘルパーによってオンザフライで作成されます。
Qt Creator は、ほとんどの Qt クラスの型情報をオンザフライで提供するため、オブジェクトのイントロスペクションのために Qt のDebugビルドを使用する必要がなくなります。
Dumper.Type クラスには、広く使われている以下のメンバ関数があります:
name- 文字列としてのこの型の名前、または型が無名である場合はNone。size(self)- この型のオブジェクトのサイズをバイト単位で返します。bitsize(self)- Bit関数は、この型のオブジェクトのサイズをビット単位で返します。alignment(self)- Alignment関数は、この型のオブジェクトに必要なアライメントをバイト単位で返します。deference(self)-None、それ以外の場合はポインタ型の参照解除型を返します。pointer(self)- この型への参照解除が可能なポインタ型を返します。target(self)- 配列型に対しては項目型を、ポインタや参照に対しては非参照型を返す便利な関数です。stripTypedefs(self)- この型がエイリアスである場合、基礎となる型を返します。templateArgument(self, position, numeric = False)- テンプレート化された型であれば、positionにあるテンプレート・パラメータを返します。numericがTrueの場合、パラメータを積分値として返します。fields(self)- この型の基本クラスとデータ・メンバを記述したDumper:Fieldsのリストを返します。
Dumper.Fieldクラス
Dumper.Field クラスは、型オブジェクトの基本クラスまたはデータ・メンバを記述します:
isBaseClass- ベース・クラスとデータ・メンバーを区別します。fieldType(self)- このベース・クラスまたはデータ・メンバーの型を返します。parentType(self)- 所有する型を返します。bitsize(self)- このフィールドのサイズをビット単位で返します。bitpos(self)- Bit関数は、所有型内のこのフィールドのオフセットをビット単位で返します。
Dumper.Valueクラス
Dumper.Value クラスは、C++ クラスのインスタンスやプリミティブなデータ型など、データの一部を記述します。また、ファイル・コンテンツ、非連続オブジェクト、コレクションなど、メモリ上で直接表現できない人工的なアイテムを記述するためにも使用できます。
Dumper.Value は、常に関連するDumper.Type を持つ。値の実際のデータには、主に2つの表現があります:
- Python
memoryviewのような Python バッファプロトコルに従った Python オブジェクト、またはbytesオブジェクトです。size()はこの値の型のサイズと一致しなければなりません。 - 現在のアドレス空間におけるオブジェクトの先頭へのポインタを表す積分値。オブジェクトのサイズは、その型の
size()で与えられる。
Dumper.Value の内部表現に関する知識は、デバッガー・ヘルパーを作成する際には通常必要ありません。
Dumper.Value クラスのメンバ関数とプロパティは以下のとおりです:
integer(self)- この値を適切なサイズの符号付き積分値として解釈して返します。pointer(self)- 現在のアドレス空間におけるポインタとしてのこの値の解釈を返します。members(self, includeBases)- この値のベース・オブジェクトとデータ・メンバを表すDumper.Valueオブジェクトのリストを返す。dereference(self)- ポインタを記述する値の場合は、参照解除された値を返し、そうでない場合はNoneを返す。cast(self, type)- この値と同じデータを持つ値を返しますが、型はtypeです。address(self)- この値が現在のアドレス空間内の連続した領域で構成されている場合はそのアドレスを返し、そうでない場合はNoneを返す。data(self)- この値のデータを Pythonbytesオブジェクトとして返します。split(self, pattern)- この値のデータからpatternに従って作成された値のリストを返します。使用可能なパターンはDumper.createTypeと同じです。dynamicTypeName(self)- この値が基底クラスオブジェクトである場合、この値の動的型の名前を取得しようとします。それが不可能な場合はNoneを返します。
子とサブ項目クラス
子項目を作成しようとすると、データが初期化されていなかったり破損している場合にエラーになることがあります。このような状況で優雅に回復するには、Children とSubItem コンテキスト・マネージャを使用して、入れ子になったアイテムを作成します。
Children コンストラクタ__init__(self, dumper, numChild = 1, childType = None, childNumChild = None, maxNumChild = None, addrBase = None, addrStep = None) は、1つの必須引数と複数のオプション引数を使用する。必須引数は現在のDumper オブジェクトを指す。オプションの引数は、子オブジェクトの数numChild を指定するために使用することができ、それぞれの孫のタイプchildType_ とchildNumChild_ があります。maxNumChild が指定された場合、その数の子だけが表示される。これは、コンテナの内容をダンプするときに使用する。パラメータaddrBase とaddrStep を使うと、子ダンプが生成するデータ量を減らすことができる。アドレスがaddrBase + n * addrStep と等しい場合、n番目の子アイテムのアドレス表示は抑制される。
例
if d.isExpanded(): with Children(d): with SubItem(d): d.putName("key") d.putItem(key) with SubItem(d): d.putName("value") d.putItem(value)
これは、次のように書くとより便利であることに注意:
d.putNumChild(2) if d.isExpanded(): with Children(d): d.putSubItem("key", key) d.putSubItem("value", value)
How To: デバッグ、デバッグ、デバッガ、デバッガも参照してください 。
Copyright © The Qt Company Ltd. and other contributors. 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.