gdb可以打破隐式类方法吗?

时间:2014-04-03 19:36:11

标签: c++ debugging gdb destructor copy-constructor

编译器生成一些类方法,如复制构造函数,析构函数等。是否可以在这些方法上使用gdb中断,例如,观察对象被复制或销毁的位置?

3 个答案:

答案 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不会破坏内联方法,因为它们通常没有可以解决的定义。