GDBでC ++ベクトルの要素を印刷するにはどうすればよいですか?


210

std::vectorGDB でaの内容を調べたいのですが、どうすればよいですか?std::vector<int>単純化するためのものだとしましょう。


3
同様の質問:stackoverflow.com/questions/427589/…(回答のリンクは非常に興味深いです)。
Paolo Tedesco、

これを実行するための新しい、より良い方法は、この質問である:stackoverflow.com/questions/2492020/...
dshepherd

回答:


79

ベクトルstd :: vector myVectorの内容を表示するには、GDBに次のように入力します。

(gdb) print myVector

これにより、次のような出力が生成されます。

$1 = std::vector of length 3, capacity 4 = {10, 20, 30}

上記を達成するには、gdb 7(私はgdb 7.01でテストしました)といくつかのpython pretty-printerが必要です。これらのインストールプロセスは、gdb wikiで説明されています

さらに、上記をインストールした後、これはEclipse C ++デバッガーGUI(および私が思うにGDBを使用する他のIDE)でうまく機能します。


16
これは、ベクトル要素が直接解釈可能である限り、正常に機能します。しかし、ベクトルに関心のあるアイテムへのポインタが含まれている場合は役に立ちません。
wallyk

率直に言って、gdb wikiページが特に読みやすくはありません。おそらく「少し」古くなっているためでしょうか?たとえば、提案されたコンテンツの内容$HOME/.gdbinitが必要だという印象がありました。現時点では、そのようなファイルはまったく存在せずgdb、のコンテンツを正しく表示していますstd::vector。ただし、「とりとめのない」試行中にインストールしてアンインストールしただけcgdbで、すでにlibstdc++5インストール済みであるため、きれいな印刷が機能しているのになぜ機能しないのか理解できません。
エンリコマリアデアンジェリス

257

GCC 4.1.2では、myVectorと呼ばれるstd :: vector <int>全体を印刷するには、次のようにします。

print *(myVector._M_impl._M_start)@myVector.size()

最初のN個の要素のみを印刷するには、次のようにします。

print *(myVector._M_impl._M_start)@N

説明

これはおそらくコンパイラのバージョンに大きく依存しますが、GCC 4.1.2の場合、内部配列へのポインタは次のとおりです。

myVector._M_impl._M_start 

そして、ポインタPで始まる配列のN個の要素を出力するGDBコマンドは次のとおりです。

print P@N

または、短い形式(標準の.gdbinitの場合):

p P@N

4
へへ、それは以前私を悩ませたものなので、今朝それを調べて、それを自分自身へのメモとして追加しました(ジェフ自身が推奨したとおり)。
ジョンカーター、

3
また、特定のベクトル要素だけが必要な場合は、myVector._M_impl._M_start + n(n番目の要素の場合)
マリナー

1
私のために働いていません。 Cannot evaluate function -- may be inlined
wallyk

1
単一の要素、たとえば2番目の要素を出力するには、次のようにします。print(myVector._M_impl._M_start)[2]
jfritz42

2
特別な名前を(見つけるには_M_implGDBの下であなたのコンパイラ7.0以降、使用するためなど)print /r myVector
同名の

14

デバッグ中にSTLコンテナを「監視」することは、やや問題があります。ここに私が過去に使用した3つの異なるソリューションがありますが、どれも完璧ではありません。

1)http://clith.com/gdb_stl_utils/の GDBスクリプトを使用します。これらのスクリプトを使用すると、ほとんどすべてのSTLコンテナーの内容を印刷できます。問題は、これがセットのスタックのようなネストされたコンテナに対して機能しないことです。

2)Visual Studio 2005は、STLコンテナーを監視するための素晴らしいサポートを備えています。これはネストされたコンテナで機能しますが、STLの実装のみであり、STLコンテナをBoostコンテナに配置する場合は機能しません。

3)デバッグ中に印刷したい特定の項目に独自の「印刷」関数(またはメソッド)を記述し、GDBで「呼び出し」を使用して項目を印刷します。印刷関数がコードのどこでも呼び出されていない場合、g ++はデッドコードの除去を行い、GDBが「印刷」関数を見つけられないことに注意してください(関数がインライン化されているというメッセージが表示されます)。したがって、-fkeep-inline-functionsを使用してコンパイルします。


11

以下を〜/ .gdbinitに入れます

define print_vector
    if $argc == 2
        set $elem = $arg0.size()
        if $arg1 >= $arg0.size()
            printf "Error, %s.size() = %d, printing last element:\n", "$arg0", $arg0.size()
            set $elem = $arg1 -1
        end
        print *($arg0._M_impl._M_start + $elem)@1
    else
        print *($arg0._M_impl._M_start)@$arg0.size()
    end
end

document print_vector
Display vector contents
Usage: print_vector VECTOR_NAME INDEX
VECTOR_NAME is the name of the vector
INDEX is an optional argument specifying the element to display
end

gdbを再起動した後(または〜/ .gdbinitをソース)、関連するヘルプを次のように表示します

gdb) help print_vector
Display vector contents
Usage: print_vector VECTOR_NAME INDEX
VECTOR_NAME is the name of the vector
INDEX is an optional argument specifying the element to display

使用例:

(gdb) print_vector videoconfig_.entries 0
$32 = {{subChannelId = 177 '\261', sourceId = 0 '\000', hasH264PayloadInfo = false, bitrate = 0,     payloadType = 68 'D', maxFs = 0, maxMbps = 0, maxFps = 134, encoder = 0 '\000', temporalLayers = 0 '\000'}}

2
コードをありがとう!タイプミスがあり、「print *($ arg0._M_impl._M_start + $ elem)@ 1」は「print *($ arg0._M_impl._M_start + $ arg1)@ 1」になるはずです。私は次の変更を使用します:$ argc == 2 if $ arg1> = $ arg0.size()-1 printf "エラー、%s.size()=%d、最後の要素の印刷:\ n"、 " $ arg0 "、$ arg0.size()-1 end print *($ arg0._M_impl._M_start + $ arg1)@ 1 else print *($ arg0._M_impl._M_start)@ $ arg0.size()end end
user1541776

エル・マグニフィコ!モカグラシアス
TruthAdjuster

0

パーティーに少し遅れたので、次の検索を行うときに、ほとんどの場合私に通知します!

私は使用することができました:

p/x *(&vec[2])@4

からvec始まる4つの要素を(16進数として)印刷しvec[2]ます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.