質問
ときどきgdbが「不完全な型」を出力するある種の変数の場合。これは何を意味し、その値をどのように見ることができますか?
解決
それは、その変数の型が不完全に指定されていることを意味します。例:
struct hatstand;
struct hatstand *foo;
GDBは、 foo
が hatstand
構造体へのポインターであることを認識していますが、その構造体のメンバーは定義されていません。したがって、「不完全なタイプ」。
値を印刷するには、互換性のある型にキャストできます。
たとえば、 foo
が実際に lampshade
構造体へのポインタであることを知っている場合:
print (struct lampshade *)foo
または、汎用ポインターとして印刷するか、整数であるかのように扱うことができます:
print (void *)foo
print (int)foo
GDBマニュアルの次のページも参照してください。
他のヒント
私が見つけたのは、不完全な構造体型gdbを使用する関数を逆アセンブルすると、構造体のメンバーが「検出」され、後で表示できることです。たとえば、文字列構造体があるとします:
struct my_string {
char * _string,
int _size
} ;
ポインターを使用して文字列を作成および取得する関数:
my_string * create_string(const char *) {...}
const char * get_string(my_string *){...}
および文字列を作成するテスト:
int main(int argc, char *argv[]) {
my_string *str = create_string("Hello World!") ;
printf("String value: %s\n", get_string(str)) ;
...
}
gdbで実行し、「* str」を印刷しようとすると、「不完全なタイプ」の応答が返されます。ただし、「逆アセンブルget_string」を試してから「print * str」を実行すると、構造体と値が正しく表示されます。なぜこれが機能するのかわかりませんが、機能します。
同じ問題がありました。ライブラリからシンボルを手動でロードする場合:
set auto-solib-add off
attach thread_id
shared any_lib
shared another_lib
同じコマンドを使用して、このオブジェクトが宣言されているライブラリからシンボルをロードする必要があります。
エラーの完全な意味はわかりませんが、Peterが指摘しているように、関連するメソッドを逆アセンブリすると、これらの型定義の一部が利用可能になります。
私の例:
クラスの.hには、そのクラスに内部ヘルパークラスの前方宣言が含まれていたため、外部クラスにそのポインターを含めることができます。対応する.cppには、完全な内部ヘルパークラス定義がありました。
外部クラスのメソッドを壊すと、gdbは、外部クラスのインスタンスを介した内部クラスインスタンスへのポインターの逆参照について不完全な型を報告しました。
外部クラスのメソッドの1つでdisasembleコマンドを発行すると、gdbは以前失敗したのと同じポインターを使用して内部クラスの構造を理解できました。
免責事項
私はC ++とLinux OSの機能について最低限の知識しか持たないpython開発者なので、以下で説明するのは個人的に経験した問題に対する私の解決策です。
サードパーティのライブラリに由来する型を使用する場合は、それらのライブラリにデバッグ情報が含まれていないことを確認してください。
例
(gdb) info share Qt
From To Syms Read Shared Object Library
0x00007ffff5336080 0x00007ffff56ba585 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
0x00007ffff4ad3510 0x00007ffff4ef0cbe Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
0x00007ffff47829c0 0x00007ffff47e1ba1 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5DBus.so.5
0x00007ffff40bb5e0 0x00007ffff439dd92 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
0x00007ffff2e581e0 0x00007ffff2e78e4f Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Xml.so.5
0x00007ffff28c8a00 0x00007ffff29d9999 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Network.so.5
0x00007ffff2251750 0x00007ffff2252a46 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5X11Extras.so.5
0x00007ffff1cc9f80 0x00007ffff1cfc861 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5PrintSupport.so.5
0x00007fffee269c10 0x00007fffee297b57 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Svg.so.5
0x00007fffed987560 0x00007fffed98b6a8 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5TextToSpeech.so.5
0x00007fffe980e130 0x00007fffe9900c0c Yes (*) /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5
0x00007fffe69ef650 0x00007fffe69ffe0d Yes (*) /usr/lib/x86_64-linux-gnu/libQt5QuickControls2.so.5
0x00007fffe5c0f890 0x00007fffe5eae1c1 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Quick.so.5
0x00007fffe5522690 0x00007fffe581f636 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Qml.so.5
0x00007fffe51996b0 0x00007fffe5221363 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5QuickTemplates2.so.5
(*): Shared library is missing debugging information.
^現在の例のすべてのQtライブラリにはデバッグ情報がありません。これは、qtライブラリのデバッグ情報がインストールされていない個別のパッケージに含まれているためです。
whatis
を実行するたびに、すべて正常に動作しました:
(gdb) whatis e
type = QEvent *
しかし、メンバーにアクセスしようとしたとき
(gdb) p e->type()
Couldn't find method QEvent::type
そして詳細な型の説明を取得しようとしています
(gdb) ptype e
type = class QEvent {
<incomplete type>
} *
ソリューション(UbuntuのQt用)
- ファイルがOSディストリビューション内のどのパッケージに属しているかを調べる
$ dpkg -S /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
libqt5core5a:amd64: /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
-
関連パッケージを検索
キーワーク
libqt5core5a
で検索すると2つのパッケージが返されます。1つはlibqt5core5a
自体で、もう1つはlibqt5core5a-dbgsym
です。後者の説明:&quot; libqt5core5aのデバッグシンボル&quot; -
デバッグシンボルを含むパッケージをインストールします(他の重要なQtライブラリのデバッグシンボルもインストールしました)
$ sudo apt install libqt5core5a-dbgsym libqt5widgets5-dbgsym libqt5gui5-dbgsym
-
gdb
でライブラリにデバッグ情報が含まれるようになりました
(gdb) info share Qt
From To Syms Read Shared Object Library
0x00007ffff5336080 0x00007ffff56ba585 Yes /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
0x00007ffff4ad3510 0x00007ffff4ef0cbe Yes /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
0x00007ffff47829c0 0x00007ffff47e1ba1 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5DBus.so.5
0x00007ffff40bb5e0 0x00007ffff439dd92 Yes /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
0x00007ffff2e571e0 0x00007ffff2e77e4f Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Xml.so.5
0x00007ffff28c7a00 0x00007ffff29d8999 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Network.so.5
0x00007ffff2250750 0x00007ffff2251a46 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5X11Extras.so.5
0x00007ffff1cc8f80 0x00007ffff1cfb861 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5PrintSupport.so.5
0x00007fffee268c10 0x00007fffee296b57 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Svg.so.5
0x00007fffed985560 0x00007fffed9896a8 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5TextToSpeech.so.5
0x00007fffe95fc130 0x00007fffe96eec0c Yes (*) /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5
0x00007fffe701f650 0x00007fffe702fe0d Yes (*) /usr/lib/x86_64-linux-gnu/libQt5QuickControls2.so.5
0x00007fffe623c890 0x00007fffe64db1c1 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Quick.so.5
0x00007fffe5b4f690 0x00007fffe5e4c636 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Qml.so.5
0x00007fffe57c66b0 0x00007fffe584e363 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5QuickTemplates2.so.5
(*): Shared library is missing debugging information.
- Qt型での作業が期待どおりに動作するようになりました
(gdb) p e->type()
$4 = QEvent::Paint
(gdb) ptype e
type = class QEvent {
public:
...
}