2017-02-25 5 views
2
https://stackoverflow.com/a/11311786/890753에 @EvanED마다 나는 새로운 표준 : : 문자열을 생성하고 gdb를 편리 변수에 넣어하기 위해 GDB 명령 newstr을 만들어으로

:호출 표준 : ~ 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를 방지하기 위해 트릭을 "무효화 할 수 캐스트"는 사용 newstr''에서는' 호출 명령. 그러나'delstr'의 마지막 명령은 항상 설정 값을 출력하는'set' 명령입니다. 그러나 나는'delstr'이 무엇이든 인쇄하는 것을 원하지 않습니다. 그 인쇄물을 피하기 위해 사용할 수있는 또 다른 트릭이 있습니까? –

+0

사실 내가 좋아하는 것은 편의 변수를 "설정 해제"하는 것이지만 gdb는 그렇게 할 수있는 방법이 없습니다. –

답변

3

TL : DR : 대신 소멸자에 0을 전달한다.

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 (3.8.1 절)을 사용하여 컴파일 된 동일한 프로그램에 추가로 int 인수가 없으므로 GCC 문제 (gcc 6.3.0 기준)가 실제로 발생합니다.


하나는 실제로 three destructors (D0, D1, D2)가있는 Italium C++ ABI에 다음 사항을 알고 있어야합니다.

GCC는 optimization -fdeclone-ctor-dtor을 가지고 있으며, 이는 세 명의 소멸자의 공통 부분을 "D4" destructor으로 리팩토링합니다. 이 "D4"소멸자는 an extra argument __in_chrg을 사용하여 가상 기본 소멸자를 호출할지 여부를 알기 위해 D0/D1/D2 중 어느 것이 소스인지 결정합니다.

이 "D4"소멸자는 어떻게 든 GCC에 의해 생성 된 DWARF 심볼의 표준 소멸자 선언으로도 사용됩니다. GDB 버그 리포트에서 링크 된 GCC issue을 확인하면 "D4"를 사용하는 이유는 GCC 개발자가 D0, D1 또는 D2 중에서 축복을 받기를 원하지 않기 때문입니다.

결과는 GDB가 무시하지 않은 여분의 int입니다.

그냥 "기본 객체 소멸자 '인 경우 소멸자 (D2)"완전한 객체 파괴 "(D0, D1), 및 0 할 때 __in_chrg2이다. 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; 
}