2013-07-23 10 views
18

とブーストのshared_ptrを調べ、私のソースコードです:には、以下のGDB

#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の値を表示したいです。私はthis linkで述べた先端を試してみましたが、動作しません

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

+0

もう一つの良い古い友人が無地のprintfであります: ) –

+1

@ Anand Rathi ...はい、でも、これがgdbで可能かどうかを知りたかっただけです。 –

答えて

28

ありがとうございました!

(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 
} 
+3

これは私が終日見た中で最も有用なものです!ありがとう、トン。私はそのようにポインタを間接参照できないことを認識しませんでした。 :-) – kmort

+3

これは私にとっては役に立ちません。 "p obj"は '$ 2 = std :: shared_ptr(count 2、weak 1)0x639268'を返し、" p obj.px "は' pxという名前のメンバまたはメソッドがありません。私も "p * obj"を試しましたが、喜びはありません: "演算子*を見つけることができませんでした。" –

0

これは難しい問題です。 GDB 7.xはPythonスクリプトのサポートを追加しました。ウェブにはいくつかのリソースがあります。むしろ私が最初の経験を持っていない何かについて助言を貧しい人々の試みを作る、私はあなたが過去の記事を参照してくださいよ:あなたが使用し-ggdbオプションをコンパイルし、それが動作するかどうかを確認すると

C++ GDB Python Pretty Printing Tutorial?

0

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

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

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

インライン関数の本体は、コールサイトに直接含まれています。インライン化されていない関数とは異なり、呼び出し専用の命令はありません。 gdbは依然として、コールサイトとインライン関数の開始が異なる命令であると主張します。コールサイトに移動すると、コールサイトが表示され、追加の命令が実行されていなくても、インライン関数の最初の行が表示されます。

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

GDBは、インライン関数の呼び出しは、通常の通話と同じであることをふりをしないいくつかの方法があります:呼び出しサイトはいずれも含まれていないため、インライン関数の呼び出し場所にブレークポイントを設定する

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

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"}}