2012-07-23 9 views
38

私はon the GDB wikiの指示に従って、STLコンテナを見るためのpython pretty-printersをインストールしました。私の~/.gdbinitは次のようになります。私は、GDBを実行し、STLのタイプを印刷しようとするとGDBでSTLコンテナをきれいに印刷するには?

python 
import sys 
sys.path.insert(0, '/opt/gdb_prettyprint/python') 
from libstdcxx.v6.printers import register_libstdcxx_printers 
register_libstdcxx_printers (None) 
end 

しかし、私は次を得る:

print myString 
Python Exception <class 'gdb.error'> No type named std::basic_string<char>::_Rep.: 
$3 = 

誰もがこの上でいくつかの光を当てることができますか?私はGDB 7.4に付属のUbuntu 12.04を実行しています。

+5

C++ライブラリの内部型とメンバ変数が変更され、Pythonモジュールが変更されていない可能性があります。 –

+0

C++ソース、コンパイラオプションなど、より多くの情報を貼り付けてください。私はこれをUbuntu 12.04でテストしたところ、私にとってはうまくいきました。 – user1202136

+0

私のためにFedora 17で動作します。 – Omnifarious

答えて

1

あなたはGNU以外のSTLライブラリを使用していると思いますが、非常に古いGCC libstdc++を使用している可能性があります。私のコンパイラでの通常のSTL文字列のタイプはstd::basic_string<char, std::char_traits<char>, std::allocator<char> >です。これはstd::basic_string<char>ではありません。

ザ・Pythonコードはそれでこれを持っている:

reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer() 

これは、どんな基本文字列型のネストされたタイプ::Rep実際にあるを見上げます。エラーメッセージは、使用している奇妙なライブラリの文字列クラスが実際に::Repネストされた型を持たないことを示しています。

7

あなたはSTLのcontainterの種類のデータ、さらにはそのデータメンバーを印刷するには(あなたの〜/ .gdbinitファイルに追加します)GDBの下でマクロを試すことができます:https://gist.github.com/3978082

2

あなたはPythonの後info type _Repを入力した場合例外として、gdbは_Repにマッチしたロードされたクラスについて通知します。このリストは、なぜpythonがあなたのstd::string classを見つけることができないのかを知るのに役立ちます。

私はちょうどあなたの問題に直面し、私のケースでは、インテルCコンパイラ、icc、誰がきれいな印刷を壊した。でstd::string結果を得るために、特に、非修飾ICC名:

std::basic_string<char, std::char_traits<char>, std::allocator<char> >::std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep; 

が、プリティプリンタは、修飾されていないgccの名前を探していた:私は私の問題はprinters.pyでクラスStdStringPrinterを修正して解決するためにやった

std::basic_string<char, std::char_traits<char>, std::allocator<char>::_Rep; 

gdbを見るために文字列の修飾されていない名前を型名に追加します。あなたがそれらを動作させるために、あなたはかなりのプリンタを修正することができinfo typeから取得したリストで

reptype = gdb.lookup_type (str (realtype) + '::' + str (realtype) + '::_Rep').pointer() 

:これで

reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer() 

:行を置き換えます。

0

私はこの問題に遭遇し、この問題を解明しようとしています。私は最終的にそれを修正し、私は私の経験を共有する価値があると思った。

私はgcc-5.2を使用していますので、svnリポジトリからpretty printerのgcc-5-branchバージョンをダウンロードしました。.gitinitファイルを編集するときに、私はエラーを取得して保持するので、提案さらにはしかし、私は、ラインregister_libstdcxx_printers (None)をコメントに

python 
import sys 
sys.path.insert(0, '/home/bartgol/.gdb/gdb_printers/python') 
from libstdcxx.v6.printers import register_libstdcxx_printers 
register_libstdcxx_printers (None) 
end 

持っていた場合)

1:しかし、私は、これら二つの改造をしなければなりませんでしたlibstdcxx_printersがすでに登録されていることを伝えます。どうやら彼らは輸入段階で登録されているようです。

2)printers.pyファイルをstd::setstd::mapに編集する必要がありました。タイプ_Rep_typeは両方ともプライベートです。特に、std::mapstd::setのルーチンchildrenを、svnリポジトリのgcc-4_6ブランチバージョンからかなりのバージョンのプリンタに置き換えました。それ以来、エラーは発生せず、今はうまく印刷されています。

これが役に立ちます。

0

それはちょうどDebianは最終的に正しく物事を統合しているように見えるのUbuntu 17.04に

に動作します:

#include <map> 
#include <utility> 
#include <vector> 

int main() { 
    std::vector<int> v; 
    v.push_back(0); 
    v.push_back(1); 
    v.push_back(2); 
    std::map<int,int> m; 
    m.insert(std::make_pair(0, 0)); 
    m.insert(std::make_pair(1, -1)); 
    m.insert(std::make_pair(2, -2)); 
} 

コンパイル:

g++ -O0 -ggdb3 -o container.out -std=c++98 container.cpp 

結果:

(gdb) p v 
$1 = std::vector of length 3, capacity 4 = {0, 1, 2} 
(gdb) p m 
$2 = std::map with 3 elements = {[0] = 0, [1] = -1, [2] = -2} 

我々がかなりプリンタがインストールされていることがわかります。

/usr/share/gcc-7/python/libstdcxx/v6/printers.py 

が付属しています:プリンタは、ファイルによってproviededさ

global pretty-printers: 
    objfile /usr/lib/x86_64-linux-gnu/libstdc++.so.6 pretty-printers: 
    libstdc++-v6 
    std::map 
    std::vector 

:行が含まれている

info pretty-printer 

メインC++ライブラリパッケージlibstdc++6は、GCCソースコードのlibstdc++-v3/python/libstdcxxの下にあります。https://github.com/gcc-mirror/gcc/blob/gcc-6_3_0-release/libstdc%2B%2B-v3/python/libstdcxx/v6/printers.py#L244

TODO:GDBが最終的なミステリーであることをGDBが見つけたのは、私のPythonパスにはありません:python -c "import sys; print('\n'.join(sys.path))"なので、どこかにハードコード化する必要がありますか?

0

上記のエラーは通常、プログラムがLLVM-build(clangでコンパイルされている)で表示され、gdb(GCCビルドプログラムで使用する)でデバッグしようとします。 理論的には、LLVMビルドプログラムはgdbでデバッグすることができ、逆も同様です。しかし 上記のような問題を避けるには、clangを使用する場合はlldbを使用し、g++を使用する場合はgdbを使用する必要があります。

関連する問題