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_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;
}
: 나는 GDB에 대해 테스트하기 위해이 프로그램을 사용하여 내가로부터 반환 값을 인쇄에서 GDB를 방지하기 위해 트릭을 "무효화 할 수 캐스트"는 사용 newstr''에서는' 호출 명령. 그러나'delstr'의 마지막 명령은 항상 설정 값을 출력하는'set' 명령입니다. 그러나 나는'delstr'이 무엇이든 인쇄하는 것을 원하지 않습니다. 그 인쇄물을 피하기 위해 사용할 수있는 또 다른 트릭이 있습니까? –
사실 내가 좋아하는 것은 편의 변수를 "설정 해제"하는 것이지만 gdb는 그렇게 할 수있는 방법이 없습니다. –