私は指示に従いました GDB wiki上 python STLコンテナーを表示するためのプリティプリンターをインストールします。私の~/.gdbinit
は次のようになります。
python
import sys
sys.path.insert(0, '/opt/gdb_prettyprint/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end
ただし、GDBを実行してSTLタイプを出力しようとすると、次のメッセージが表示されます。
print myString
Python Exception <class 'gdb.error'> No type named std::basic_string<char>::_Rep.:
$3 =
誰でもこれに光を当てることができますか? GDB 7.4に付属するUbuntu 12.04を実行しています。
以下で試すことができますGDBマクロ(あなたの〜/ .gdbinitファイル)STLコンテナータイプデータとそのデータメンバーさえも印刷します: https://Gist.github.com/3978082
Gccのバージョンを確認してください。 4.7未満の場合は、別のprinter.pyファイルを使用する必要があります。 http://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch/libstdc++-v3/python/ からファイルを取得します。
あなたが言及したリンク にリストされているメソッドの代わりに、スクリプト here を試すことができます。
次のようにします。
1)スクリプトを/your/path
にダウンロードします。名前を付けてくださいyour_name.conf
。
2)~/.gdbinit
ファイルがない場合は、ホームディレクトリに追加します。
3)source /your/path/your_name.conf
行に~/.gdbinit
を追加します。
4)gdbを再起動します。 pvector
を試してください
help pvector
などのコマンドでヘルプ情報を見つけることができます。
例えば.
pvector vec 5 # Prints element[5] in vec
pvector vec 5 10 # Prints elements in range [5, 10] in vec. (5, 6, 7, 8, 9, 10)
参考までに、 スクリプト は、STLの要素を出力する機能を持つgdbにいくつかのコマンド(pvector
、plist
、pmap
など)を追加します。また、print pretty
を追加して、次のようなNice形式を生成します。
また、gdbでSTLの要素に正確にアクセスする方法を知りたい場合は、コマンドのコードを読むだけです。コードには秘密はありません。 ^ _ ^
例えばベクトルは._M_impl._M_start
によってアクセスされます
p vec._M_impl._M_start + 4 # prints vec[4]
Ubuntu 17.04でのみ動作します
Debianはようやく物事を適切に統合したようです。
_#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}
_
プリティプリンタがインストールされていることがわかります。
_info pretty-printer
_
次の行が含まれます:
_global pretty-printers:
objfile /usr/lib/x86_64-linux-gnu/libstdc++.so.6 pretty-printers:
libstdc++-v6
std::map
std::vector
_
プリンターにはファイルが用意されています。
_/usr/share/gcc-7/python/libstdcxx/v6/printers.py
_
これは、メイン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がそのファイルを見つける方法は最終的な謎であり、私のPython path:python -c "import sys; print('\n'.join(sys.path))"
にないので、どこかにハードコーディングする必要がありますか?
Python例外の後にinfo type _Rep
と入力すると、gdbは_Repに一致するロードされたクラスについて通知します。このリストは、pythonがstd::string class
を見つけられない理由を見つけるのに役立ちます。
私はあなたの問題に直面したばかりで、私の場合はintel 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名を探していました:
std::basic_string<char, std::char_traits<char>, std::allocator<char>::_Rep;
私の問題を解決するためにやったことは、printers.pyのクラスStdStringPrinter
を修正し、文字列の非修飾名をtypenameに追加してgdbを調べることでした。行を置き換える:
reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
これとともに:
reptype = gdb.lookup_type (str (realtype) + '::' + str (realtype) + '::_Rep').pointer ()
info type
から取得したリストを使用して、きれいなプリンターを修正して機能させることができます。
私はこの問題を実行し、それを理解しようとしてこのページにヒットしました。私は最終的にそれを修正し、私の経験を共有する価値があると思いました。
私はgcc-5.2を使用しているため、svnリポジトリからgcc-5-branchバージョンのプリティプリンターをダウンロードしました。ただし、次の2つのmodを実行する必要がありました。
1).gitinitファイルを編集する場合、推奨される追加は
_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
_
ただし、libstdcxx_printersがすでに登録されているというエラーが表示され続けたため、register_libstdcxx_printers (None)
行をコメント化する必要がありました。どうやら、それらはインポート段階で登録されます。
2)_std::set
_および_std::map
_のprinters.pyファイルを編集する必要がありました。タイプ__Rep_type
_は両方ともプライベートであるため。特に、_std::map
_および_std::set
_のchildren
ルーチンを、svnリポジトリのgcc-4_6-branchバージョンのプリティプリンターのバージョンの対応するルーチンに置き換えます。それ以来、エラーは発生していませんでした。
お役に立てれば。
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
ネスト型を持たないことを示しています。
上記のようなエラーは通常、プログラムがLLVMビルド(clang
でコンパイル)であり、gdb
(GCCビルドプログラムに使用する必要があります)でデバッグしようとすると表示されます。理論的には、LLVMビルドプログラムはgdb
でデバッグでき、その逆も可能です。ただし、上記のような問題を回避するには、lldb
を使用する場合はclang
を使用し、g++
を使用する場合はgdb
を使用する必要があります。