gdbを使用した標準コンテナー(std :: map)の内容の検査


93

次のようなものがあるとします。

#include <map>
int main(){
    std::map<int,int> m;
    m[1] = 2;
    m[2] = 4;
    return 0;
}

gdbからプログラムを実行しているマップの内容を検査できるようにしたいと思います。
添え字演算子を使用すると、次のようになります。

(gdb) p m[1]
Attempt to take address of value not located in memory.

findメソッドを使用しても、より良い結果は得られません。

(gdb) p m.find(1)
Cannot evaluate function -- may be inlined

これを達成する方法はありますか?

回答:


35

少なくとも、ソースが最適化されている場合などはそうではないと思います。ただし、STLコンテナを検査できるgdbのマクロがいくつかあります。

http://sourceware.org/ml/gdb/2008-02/msg00064.html

しかし、私はこれを使用しないので、YMMV


1
リンクありがとうございます。唯一のことは、マクロがstlライブラリのバージョンに依存していることです。これは避けたいと思います。+1
Paolo Tedesco、

また、「plist foo std :: string」のようなコマンドが構文エラーを表示することは少しイライラします。value_typeには句読点を含めることができないようです。
Bklyn、2009年

2
私は試していませんが、これがGDBの他の部分と同じように機能する場合は、名前を句読点付きの名前で単一引用符で囲むことでそれを実行できます。
jpalecek 2009年

2
注:これらのスクリプトのstd :: map機能は、32ビットポインター型を想定しています。64ビットマシンの場合、ファイルのすべての場所で「+ 4」を「+ 8」に置き換えます。
Kyle Simek、2012年

pvectorがgdb(バージョン7.5.91.20130417-cvs-ubuntu)で定義されていません。
ジェフ

91

この質問に対する既存の回答は非常に古くなっています。最近のGCCとGDBでは、GDB 7.xの組み込みPythonサポートと、GCCに付属するlibstdc ++プリティプリンターのおかげで、Just Works TMになりました。

OPの例では、次のようになります。

(gdb) print m
$1 = std::map with 2 elements = {[1] = 2, [2] = 4}

自動的に機能しない場合は、GDB wikiのSTLサポートページの最初の箇条書きを参照してください。

独自のタイプのPythonプリティプリンターを作成することもできます。GDBマニュアルのプリティプリンティングを参照してください。


2
はい。ただし、他の質問は重複してクローズされているので、最近の情報を知りたいと思いました。
Jonathan Wakely 2013年

1
私はGDB 7.2を使用していますが、上記の作品は...小さなコレクションを持っている場合。STL実装の内部構造を使用する以外に、4Kベクトルからsay要素1543を出力する方法はまだ見つかりません。
pavon 2013年

5
はい、GDB 7.2とicpcコンパイラではエラーが発生しますCould not find operator[]
2013年

11
残念ながら、それはすべてのディストリビューションで「ちょうど働く」わけではありません。Ubuntu 13.10ではデフォルトではインストールされず、手動でインストールしようとすると問題
nietaki

1
@ razeh、Fedora、RHEL(およびRHELクローン)。GDBがPython 3にリンクされているディストリビューションでもプリンターを動作させるための進行中の修正があります
Jonathan Wakely 2014

25

常に明白です:独自のテスト関数を定義します... gdbから呼び出します。例えば:

#define SHOW(X) cout << # X " = " << (X) << endl

void testPrint( map<int,int> & m, int i )
{
  SHOW( m[i] );
  SHOW( m.find(i)->first );
}

int
main()
{
    std::map<int,int> m;
    m[1] = 2;
    m[2] = 4;
    return 0;  // Line 15.
}

そして:

....
Breakpoint 1 at 0x400e08: file foo.C, line 15.
(gdb) run
Starting program: /tmp/z/qD 

Breakpoint 1, main () at qD.C:15
(gdb) call testPrint( m, 2)
m[i] = 4
(*m.find(i)).first = 2
(gdb) 

16
プロセスが実行されている限り。コアダンプにはあまり役に立ちません。
ショーンライリー

2
これは、STLだけでなく、一般にGDBのデバッグに役立つアドバイスです。取得が困難な多くのデータ、たとえばwrite_cuda_array_as_image()のgdbヘルパー関数のライブラリ全体を保持しています。一部のコンパイラは呼び出されない関数を削除することに注意してください。そのため、メインの「return 0;」の後に各ヘルパー関数を呼び出します。また、それらをextern "C"で宣言すると、gdbからの呼び出しが簡単になります。
Kyle Simek、2012年

21

stl-views.gdbもうあったではなく、最良の答えにするために使用。

これはGDBまだメインラインに統合されていませんが、 'archer-tromey-python' ブランチを使用すると次のようになります。

(gdb) list
1   #include <map>
2   int main(){
3       std::map<int,int> m;
4       m[1] = 2;
5       m[2] = 4;
6       return 0;
7   }
(gdb) break 6
Breakpoint 1 at 0x8048274: file map.cc, line 6.
(gdb) run

Breakpoint 1, main () at map.cc:6
6       return 0;
(gdb) print m
$1 = std::map with 2 elements = {
  [1] = 2,
  [2] = 4
}
(gdb) quit

12

STLコンテナの逆参照を試す:このページ:http : //www.yolinux.com/TUTORIALS/GDB-Commands.html


これらはビジネスに見えます!
Richard Corden、

これらは実際には前の回答と同じマクロです:)簡単な解決策はありません。
Paolo Tedesco、

コマンドとは?あなたは大量の無関係な情報を使ってオフサイトで実行することができました。「GDBの始め方」などには興味がありません。
jww

1

上記の答えは機能していて問題ありません。stl-views.gdbを使用している場合、その中にあるマップと要素を表示する適切な方法は次のとおりです。あなたの地図は次のようにしましょう: std::map<char, int> myMap;

(gdb) pmap myMap char int

つまりpmap <variable_name> <left_element_type> <right_element_type>、マップ内の要素を表示します。

お役に立てば幸いです。


0

Cannot evaluate function -- may be inlinedプログラムをコンパイルするときにコンパイラがDWARF-2(または3または4)のデバッグ情報を使用することを確認することで、2番目の問題()を回避できます。DWARF-2にはインライン化情報が含まれているため、説明した方法のいずれかを使用してstd::mapコンテナーの要素にアクセスできます。

DWARF-2デバッグ情報-gdwarf-2を使用してコンパイルするには、コンパイルコマンドにフラグを追加します。


1
ええと、関数がインライン化されている場所を知っていても、GDBがその関数の呼び出しを評価することはできません。GDBは、実際には関数のアウトオブラインコピーにアクセスする必要があります。
SamB 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.