web-dev-qa-db-ja.com

gdbでboostshared_ptrを調べます

以下は私のソースコードです:

#include <iostream>
#include <boost/shared_ptr.hpp>

class MyClass
{
    public:
        MyClass()
        {
            i=10;
        }
    private:
        int i;
};


int main(int argc, const char *argv[])
{
    boost::shared_ptr <MyClass> obj(new MyClass());
    return 0;
}

Gdbのobjを調べて、メンバー変数iの値を表示したいと思います。

これは私が通常の印刷で得るものです:

29          boost::shared_ptr <MyClass> obj(new MyClass());
(gdb) n
30          return 0;
(gdb) p obj
$1 = {px = 0x602010, pn = {pi_ = 0x602030}}

このリンク に記載されているヒントを試しましたが、機能しません。

(gdb) call (obj.get())->print()
Cannot evaluate function -- may be inlined

他に方法はありますか? gdbのバージョンは7.0.1です。

19
m.divya.mohan

とった。!

(gdb) set print pretty
(gdb) p obj
$5 = {
  px = 0x602010,
  pn = {
    pi_ = 0x602030
  }
}
(gdb) p obj.px
$6 = (MyClass *) 0x602010



(gdb) p *(obj.px)
$7 = {
  i = 10
}
30
m.divya.mohan

これを試して:

印刷(* obj.px).i

完全なコードは以下のとおりです。

 (gdb) list 1,23
1       #include <iostream>
2       #include <boost/shared_ptr.hpp>
3       #include <string>
4
5       class MyClass
6       {
7           public:
8               MyClass()
9                   : name("Testing")
10              {
11                  i=10;
12              }
13          private:
14              int i;
15              std::string name;
16      };
17
18
19      int main(int argc, const char *argv[])
20      {
21          boost::shared_ptr <MyClass> obj(new MyClass());
22          return 0;
23      }
(gdb) p obj
$9 = {px = 0x602010, pn = {pi_ = 0x602060}}
(gdb) p (*obj.px).i
$10 = 10
(gdb) p (*obj.px).name
$11 = {static npos = 18446744073709551615,
  _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>},
    _M_p = 0x602048 "Testing"}}
2
Ganesh M

これは答えるのが難しいでしょう。 GDB7.xが追加されましたPythonスクリプトのサポート。Web上にいくつかのリソースがあります。私が最初に経験したことのないことについてアドバイスするのではなく、紹介します。過去の投稿へ:

C++ GDB Pythonプリティプリントチュートリアル?

0
dans3itz

コンパイルするときは、-ggdbオプションを使用して、それが機能するかどうかを確認してください

http://sourceware.org/gdb/onlinedocs/gdb/Inline-Functions.html

インライン化は、共有ルーチンにジャンプするのではなく、関数本体のコピーを各呼び出しサイトに直接挿入する最適化です。 gdbは、非インライン関数と同じようにインライン関数を表示します。それらはバックトレースに表示されます。それらの引数とローカル変数を表示し、stepでそれらにステップインし、nextでそれらをスキップし、finishでそれらから脱出することができます。 info frameコマンドを使用して、関数がインライン化されているかどうかを確認できます。

Gdbがインライン関数をサポートするには、コンパイラーがインライン化に関する情報をデバッグ情報に記録する必要があります。dwarf2形式を使用するgccがこれを行い、他のいくつかのコンパイラーもこれを行います。 gdbは、dwarf 2を使用する場合にのみ、インライン関数をサポートします。4.1より前のバージョンのgccは、2つの必須属性(「DW_AT_call_file」と「DW_AT_call_line」)を生成しません。 gdbは、以前のバージョンのgccではインライン関数呼び出しを表示しません。代わりに、インライン関数の引数とローカル変数を呼び出し元のローカル変数として表示します。

インライン関数の本体は、その呼び出しサイトに直接含まれています。インライン化されていない関数とは異なり、呼び出し専用の命令はありません。 gdbは、呼び出しサイトとインライン関数の開始が異なる命令であるかのように見せかけます。呼び出しサイトにステップすると呼び出しサイトが表示され、次にもう一度ステップすると、追加の命令が実行されていなくても、インライン関数の最初の行が表示されます。

これにより、ソースレベルのデバッグがはるかに明確になります。通話のコンテキストと、通話の効果の両方を確認できます。 stepiまたはnextiを使用して単一の命令でステップするだけでは、これは行われません。単一の命令ステップでは、常にインライン化された本文が表示されます。

インライン関数呼び出しが通常の呼び出しと同じであるとgdbが偽装しない方法がいくつかあります。

インライン関数の呼び出しサイトにブレークポイントを設定すると、呼び出しサイトにコードが含まれていないため、機能しない場合があります。 gdbは、呼び出し後に、ブレークポイントを囲んでいる関数の次の行に誤って移動する場合があります。この制限は、gdbの将来のバージョンで削除される予定です。それまでは、代わりに前の行またはインライン関数内にブレークポイントを設定してください。 gdbは、finishコマンドを使用した後、インライン呼び出しの戻り値を見つけることができません。これは、コンパイラーが生成するデバッグ情報の制限です。終了後、次の行に進んで、プログラムが戻り値を格納した変数を出力できます。

0
Anand Rathi