20

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

#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 です。

4

4 に答える 4

30

とった。!

(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
}
于 2013-07-23T10:06:07.553 に答える
2

これを試して:

印刷 (*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"}}
于 2013-07-25T05:25:43.670 に答える
0

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

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

于 2013-07-23T08:27:32.617 に答える
0

コンパイル時に -ggdb オプションを使用して、それが機能するかどうかを確認します

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

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

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

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

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

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

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

于 2013-07-23T08:36:04.877 に答える