2017-02-25 17 views
2
https://stackoverflow.com/a/11311786/890753に@EvanEDごとに、私は新しいのstd ::文字列を作成して、gdbのコンビニエンス変数でそれを置くためにGDBコマンド newstrを作成したとして

呼び出しのstd ::〜GDBでのbasic_string()

define newstr 
set ($arg0)=(std::string*)malloc(sizeof(std::string)) 
call ($arg0)->basic_string() 
# 'assign' returns *this; casting return to void avoids printing of the struct. 
call (void)(($arg0)->assign($arg1)) 
end 

それを素晴らしい作品:

define delstr 
call ($arg0)->~basic_string($arg0) 
call free($arg0) 
set ($arg0)=(void*)0 
end 
:tidynessのために私も delstrを作成したので

(gdb) newstr $foo "hello world" 
(gdb) p $foo->c_str() 
$57 = 0xb22e388 "hello world" 

は、私は、他のカスタムGDBコマンドでnewstrを使用

それは動作しますが、デストラクタの呼び出しは、迷惑なメッセージが生成します。

(gdb) delstr $foo 
warning: Using non-standard conversion to match method std::string::~basic_string to supplied arguments 
$62 = 0 

は、私が「非標準変換」メッセージを回避することはできますか? (私はgdb 7.10を使用しています)

+0

:私はGDBに対してテストする場合は、このプログラムを使用し、私はからの戻り値を印刷からGDBを防ぐためにトリックを「voidにキャスト」使用newstr' 'で'コール 'コマンド。しかし、 'delstr'の最後のコマンドは' set'です。これは常に設定された値を出力します。しかし、私は 'delstr'が何かを印刷するのを望んでいません。そのプリントを避けるために使うことができる別のトリックがありますか? –

+0

実際、私は_really_好きなのは便利変数を "設定解除"することですが、gdbはそれを行う方法がありません - そうですか? –

答えて

3

TL; DR:0$fooの代わりにデストラクタに渡してください。

define delstr 
call ($arg0)->~basic_string(0) 
#       ^
call free($arg0) 
set ($arg0)=(void*)0 
end 

OKだから何が起こっている...私たちは、最初のデストラクタの署名を確認することができます。それは確かに整数を取ります。

(gdb) p ((Foo*) 0)->~Foo 
$1 = {void (Foo * const, int)} 0x555555554c00 <Foo::~Foo()> 

(gdb) p (('std::__cxx11::string'*) 0)->~basic_string 
$2 = {void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > * const, int)} 0x7ffff7b75010 <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()> 

(gdb) ptype Foo 
type = struct Foo { 
    public: 
    Foo(void); 
    ~Foo(int); 
} 

だから、「非標準変換」警告が実際に非標準である整数、ポインタの変換についてです。 (警告はデストラクタとは何も関係ありません)

しかし、最初に何らかの理由でデストラクタに余分な整数を渡す必要がありますか?それは... a bug実際にはclangを使ってコンパイルされた同じプログラム(clang 3.8.1以降)にはint引数がないため、GCCの問題(gcc 6.3.0以降)が実際に発生します。


一つはItalium C++ ABIに実際にthree destructorsD0, D1, D2)がある、ということを知っている必要があります。

GCCには、optimization -fdeclone-ctor-dtorがあり、3つのデストラクタの共通部分を"D4" destructorにリファクタリングします。この "D4"デストラクタは、仮想ベースデストラクタを呼び出すかどうかを知るために、D0/D1/D2のどれがソースかを判断するのにan extra argument __in_chrgをとります。

この「D4」デストラクタは、GCCによって生成されたDWARFシンボルの標準的なデストラクタ宣言として、何らかの形で使用されています。 GDBのバグレポートからリンクされているGCC issueをチェックすると、GCC開発者がD0、D1、またはD2のどれを祝福したくないのかが理由で「D4」を使用する理由があります。

結果は、GDBが無視しなかった余分なintです。それだけ「ベースオブジェクトのデストラクタ」(D2)である場合デストラクタ「は、完全なオブジェクトの破壊」(D0、D1)、及び0できる場合

__in_chrg値は2あります。 std::stringには仮想基本クラスがないので、その引数に0を渡すだけです。


注:また

#include <string> 
#include <iostream> 
std::string aa; 
struct Foo { 
     Foo() { std::cout << "Constructing: this = " << this << std::endl; } 
     ~Foo() { std::cout << "Destroying: this = " << this << std::endl; } 
}; 
int main() { 
     Foo foo; 
     return 0; 
} 
関連する問題