2016-09-24 9 views
20

非常に基本的なSTLをデバッグするために、Xcode 8でLLDBを使用しようとしています。私はこのようなベクトルを印刷することができました。Xcode/LLDBでlibC++ STLを印刷/デバッグ

p myvector[0] 

最初のベクトルインデックスにあったものは何でも見ることができます。

p myvector.__begin_[0] in order to get any output. 

私はLLDBのSVNリポジトリからlibcxx.pyとunordered_multi.pyスクリプトをインポートしようとした:私はこれを入力する必要があり、その代わり

error: Couldn't lookup symbols: 
    __ZNSt3__16vectorI9my_classNS_9allocatorIS1_EEEixEm 

:私はそれを行う際に今、私はこのエラーを取得しますしかしそれは何も変わらないようです。

誰もlibC++でLLDBから有用な出力を得ることができましたか?

+0

デバッグ情報でコンパイルしましたか?自己完結型の再生装置を提供できますか? – EricWF

+1

もちろん、デバッグ情報は有効です。 :)問題を再現できるダムプロジェクトです。 std :: cout行にブレークポイントを設定し、ヒットするとlldbコマンド "p myVector [0]"を実行するだけです。エラーが発生します。代わりに "p myVector .__ begin_ [0]"を実行すると、うまく印刷されます。 https://www.dropbox.com/s/ntjywxabxj3e4mc/Crap.zip?dl=0 – cjserio

答えて

47

[]は、std::vectorの演算子メソッドであるため、必要な式を印刷するために、lldbは[]メソッドを呼び出すことができなければなりません。ここで問題となるのは、OS XのSTLは可能な限りインライン展開を行い、同じ機能の行外コピーを生成するスペースを無駄にしないことです。最適化されたコードには最適ですが、デバッガには[]オペレータを呼び出さないため、デバッグにはあまり適していません。それはあなたが見ているエラーメッセージです。

このベクターの要素を見たい場合は、lldb 「STLデータフォーマッタ」を使用してこの作業を行うことができます。彼らはほとんどのSTL型がどのように配置されているかを知っており、ほとんどのコンテナ型の要素を出力できます。例えば:

(lldb) expr my_vec[0] 
error: Couldn't lookup symbols: 
    __ZNSt3__16vectorI3FooNS_9allocatorIS1_EEEixEm 

しかし:

(lldb) expr my_vec 
(std::__1::vector<Foo, std::__1::allocator<Foo> >) $0 = size=2 { 
    [0] = (var1 = 10, var2 = 20) 
    [1] = (var1 = 10, var2 = 20) 
} 

データフォーマッタに静的オブジェクト、及びフックを検査することができる別のコマンド「フレーム変数」もあります。これは、関数を呼び出し、他のより複雑な式パーサの作業を行うが、それは個々の要素を取得するために、STLデータフォーマッタを使用する方法を知っているんではないことができます。

あなたもの要素を見つけるために、フレームのVARの -Lオプションを使用することができます
(lldb) frame var my_vec[1] 
(Foo) my_vec[1] = (var1 = 10, var2 = 20) 

ベクトルの、そしてあなたは他の関数に渡すアドレスをキャストすることができます:デバッグのためにこの問題を回避するために

(lldb) frame var -L my_vec[1] 
0x0000000100100348: (Foo) my_vec[1] = { 
0x0000000100100348: var1 = 10 
0x000000010010034c: var2 = 20 
} 
(lldb) expr printf("%d\n", ((class Foo *) 0x0000000100100348)->var1) 
10 
(int) $3 = 3 

もう一つの方法 - あなたがC++ 11を使用している場合 - 置くことである:

template class std::vector<MyClass> 
あなたのコードのどこかに

これは、コンパイラーに、この特殊化のためのすべてのテンプレート関数のアウトラインのコピーを発行するよう指示します。これは大きな一般的な解決策ではなく、デバッグビルド用にのみ行いたいだけですが、これらの関数を呼び出して複雑な式で使用できるようにします。

+1

非常に徹底的な答えジム、私はそれを感謝します! – cjserio

+0

これをブックマークする。非常に役立ちます! –

+0

私はLinux(Ubuntu 16.10)でclang/lldb 3.9と同じ動作をしています。しかし、gcc/gdbは '(gdb)p my_vec [0]'に問題はありません。彼らが何をやっているのだろうか。 –