web-dev-qa-db-ja.com

gdbで<incomplete type>変数を出力する方法

場合によっては、gdbが一部のタイプの変数について「不完全なタイプ」を出力することがあります。これは何を意味し、どのようにその値を見ることができますか?

45
grigy

これは、その変数のタイプが不完全に指定されていることを意味します。例えば:

struct hatstand;
struct hatstand *foo;

GDBはfoohatstand構造体へのポインターであることを認識していますが、その構造体のメンバーは定義されていません。したがって、「不完全型」です。

値を出力するには、互換性のある型にキャストできます。

たとえば、fooが実際にlampshade構造体へのポインターであることを知っている場合:

print (struct lampshade *)foo

または、汎用ポインタとして出力するか、整数のように扱うことができます。

print (void *)foo
print (int)foo

GDBマニュアルの次のページも参照してください。

29
Daniel Cassidy

私が見つけたのは、不完全な構造体型を使用する関数を逆アセンブルすると、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で実行し、「print * str」を実行すると、「不完全なタイプ」の応答が返されます。ただし、「disassemble get_string」を実行してから「print * str」を実行すると、構造体と値が正しく表示されます。なぜこれが機能するのかはわかりませんが、機能します。

5
Peter

エラーの完全な意味はわかりませんが、Peterが指摘しているように、関連するメソッドの逆アセンブリは、これらの型定義の一部を利用できるようにするものです。

私の例:

クラスの.hでは、そのクラスに内部ヘルパークラスの前方宣言が含まれているため、外部クラスはそれへのポインターを含むことができます。対応する.cppには、完全な内部ヘルパークラス定義がありました。

外部クラスのメソッドに割り込むと、gdbは、外部クラスのインスタンスを介した内部クラスインスタンスへのポインターの逆参照の不完全な型を報告しました。

外部クラスのメソッドの1つでdisasembleコマンドを発行すると、gdbは以前に失敗したのと同じポインタを使用して内部クラスの構造を理解できました。

0
memerson

私も同じ問題を抱えていました。ライブラリからシンボルを手動でロードする場合:

set auto-solib-add off
attach thread_id
shared any_lib
shared another_lib

同じコマンドを使用して、このオブジェクトが宣言されているライブラリからシンボルをロードする必要もあります。

0
isilpekel

Dislamer

私はpython開発者であり、C++とLinux OSの機能について最低限の知識しか持っていないため、以下で説明するのは私が個人的に経験した問題に対する私の解決策です。

サードパーティのライブラリからの型を使用する場合は、それらのライブラリにデバッグ情報が欠落していないことを確認してください。

(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 libsのデバッグ情報が、インストールされていない個別のパッケージに入っているためです。

私が_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の場合)

  1. OSディストリビューション内のどのパッケージにファイルが属しているかを見つける
$ dpkg -S /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
libqt5core5a:AMD64: /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
  1. 関連パッケージを検索

    キーワークで検索libqt5core5aは2つのパッケージを返しました。1つはlibqt5core5a自体、もう1つはlibqt5core5a-dbgsym。後者の説明には、「libqt5core5aのデバッグシンボル」とあります。

  2. デバッグシンボルを含むパッケージをインストールします(他の重要なQtライブラリのデバッグシンボルもインストールしました)

$ Sudo apt install libqt5core5a-dbgsym libqt5widgets5-dbgsym libqt5gui5-dbgsym
  1. 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.
  1. Qt型の操作が期待どおりに機能するようになりました
(gdb) p e->type()
$4 = QEvent::Paint
(gdb) ptype e
type = class QEvent {
  public:
...
}
0
I. Yegor