编译器生成一些类方法,如复制构造函数,析构函数等。是否可以在这些方法上使用gdb中断,例如,观察对象被复制或销毁的位置?
答案 0 :(得分:4)
gdb可以打破隐式类方法吗?
是的,当然可以。
(gdb) break MyClass::MyClass(const MyClass &) // break when copied
(gdb) break MyClass::~MyClass() // break when object destroyed
就这么简单。这些是基于断点的,不是文件:行,而是函数名称。如果你有一个包装类的命名空间,那么请确保为它提供完全限定的名称,例如
(gdb) break NyNamespace::MyClass::MyClass(const MyClass &)
查看here以获取在GDB中指定断点的方法列表。
答案 1 :(得分:1)
gdb可以破坏debuginfo中提到的任何内容或作为ELF sybmol。我不知道你的编译器是否为这些人工方法发出了debuginfo。
答案 2 :(得分:0)
我有类似的需求,我用
构建了我的代码g++ main.cpp -std=c++1y -o app_name -g -ggdb
但是gdb无法看到我的implict构造函数和赋值运算符符号。因此,它不会打破它们。 因为我已经使用这个hack能够打破隐式定义的被检查类的方法:只需用您熟悉的明确定义的方法实现自己的类。然后将这个新类对象添加为数据成员您要调试的类。在新类的方法上设置断点。请享用!
示例:
class LifeCycleInspector
{
public:
LifeCycleInspector()
{
printf( "Default C-tor\n" );
}
LifeCycleInspector( const LifeCycleInspector& )
{
printf( "Copy C-tor\n" );
}
LifeCycleInspector( LifeCycleInspector&& )
{
printf( "Move C-tor\n" );
}
LifeCycleInspector& operator=( const LifeCycleInspector& )
{
printf( "Copy A-ment\n" );
return *this;
}
LifeCycleInspector& operator=( LifeCycleInspector&& )
{
printf( "Move A-ment\n" );
return *this;
}
virtual ~LifeCycleInspector()
{
printf( "D-tor\n" );
}
};
class Test
{
private:
LifeCycleInspector lci_;
};
void foo()
{
Test t1;
Test t2( t1 );
Test t3;
t3 = t1;
Test t4( std::move( t3 ) );
Test t5;
t5 = std::move( t4 );
}
int main()
{
foo();
return 0;
}
输出样本:
Default C-tor
Copy C-tor
Default C-tor
Copy A-ment
Move C-tor
Default C-tor
Move A-ment
D-tor
D-tor
D-tor
D-tor
D-tor
重要!如果您将方法设为空,例如:
LifeCycleInspector( const LifeCycleInspector& )
{
}
- 您的编译器优化可能会做一些奇特的事情,您的调试输出可能会很奇怪。在这种情况下,您可以在方法中添加一些例程以防止优化。此外,您应该将方法实现从类移动到其标头或源,因为在类的正文中定义方法是隐式地使此方法成为内联的候选者。 gdb不会破坏内联方法,因为它们通常没有可以解决的定义。