web-dev-qa-db-ja.com

GDBでSTLコンテナーをきれいに印刷する方法は?

私は指示に従いました 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を実行しています。

44
Nick Hutchinson

以下で試すことができますGDBマクロ(あなたの〜/ .gdbinitファイル)STLコンテナータイプデータとそのデータメンバーさえも印刷します: https://Gist.github.com/3978082

10
Fei

Gccのバージョンを確認してください。 4.7未満の場合は、別のprinter.pyファイルを使用する必要があります。 http://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch/libstdc++-v3/python/ からファイルを取得します。

4
Bingfeng

あなたが言及したリンク にリストされているメソッドの代わりに、スクリプト 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にいくつかのコマンド(pvectorplistpmapなど)を追加します。また、print prettyを追加して、次のようなNice形式を生成します。

enter image description here

また、gdbでSTLの要素に正確にアクセスする方法を知りたい場合は、コマンドのコードを読むだけです。コードには秘密はありません。 ^ _ ^

例えばベクトルは._M_impl._M_startによってアクセスされます

p vec._M_impl._M_start + 4 # prints vec[4]

3
Scott Yang

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から取得したリストを使用して、きれいなプリンターを修正して機能させることができます。

2
Manuel Núñez

私はこの問題を実行し、それを理解しようとしてこのページにヒットしました。私は最終的にそれを修正し、私の経験を共有する価値があると思いました。

私は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バージョンのプリティプリンターのバージョンの対応するルーチンに置き換えます。それ以来、エラーは発生していませんでした。

お役に立てれば。

2
bartgol

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ネスト型を持たないことを示しています。

1
Omnifarious

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

0
Ans