gdb可以在隐式类方法上中断吗?

时间:2021-11-11 23:39:11

The compiler generates some class methods like copy constructors, destructors, etc. Is it possible to have gdb break on those methods to, e.g., observe where objects are being copied or destroyed?

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

3 个解决方案

#1


4  

Can gdb break on implicit class methods?

gdb可以在隐式类方法上中断吗?

Yes, of course, it can.

是的,当然可以。

(gdb) break MyClass::MyClass(const MyClass &)     // break when copied
(gdb) break MyClass::~MyClass()                   // break when object destroyed

as simple as that. These are breakpoints based, NOT on file:line, but on function names. If you've a namespace wrapping the class then make sure you give the fully qualified name for it e.g.

那么简单。这些是基于断点的,不是基于file:line,而是基于函数名。如果您有一个名称空间包装类,那么请确保为它提供完全限定的名称,例如。

(gdb) break NyNamespace::MyClass::MyClass(const MyClass &)

Look here for a list of ways to specify breakpoints in GDB.

在这里寻找在GDB中指定断点的方法列表。

#2


1  

gdb can break on anything that is either mentioned in the debuginfo or as an ELF sybmol. Offhand I do not know whether your compiler emits debuginfo for these artificial methods.

gdb可以破坏debuginfo中提到的任何内容,或者作为一个ELF sybmol。我不知道您的编译器是否会为这些人工方法发出debuginfo。

#3


0  

I have similar needs, I built my code with

我有类似的需求,我用它来构建代码

g++ main.cpp -std=c++1y -o app_name -g -ggdb

but gdb can't see my implict constructors and assignment operators symbols. And for this reason it don't break on them. Because of that I've used this hack to be able to break on implicitly defined methods of examined class: just implement your own class with explicitly defined methods you're interesting in. Then add this new class object as data member of class you want to debug. Set breakpoints on methods of new class. Enjoy!

但是gdb看不到隐含构造函数和赋值运算符的符号。因为这个原因,它不会断裂。正因为如此,我使用了这一技巧来突破已检查类的隐式定义方法:只需使用感兴趣的显式定义方法实现您自己的类。然后将这个新的类对象添加为要调试的类的数据成员。在新类的方法上设置断点。享受吧!

Example:

例子:

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;
}

Output sample:

输出样例:

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

Important! If you make your methods empty, like:

重要!如果你的方法是空的,比如:

LifeCycleInspector( const LifeCycleInspector& )
{   
}

- your compiler optimization may do fancy things and your debug output may be pretty strange. In this case you may add some routine to the methods to prevent optimization. Also you should move methods implementation from class to its header or source, as defining method right in class's body is implicitly making this method an candidate for inlining. gdb will not break on inlined methods because they usually have no definition which could be adressed.

-你的编译器优化可能会做一些奇特的事情,你的调试输出可能会很奇怪。在这种情况下,您可以在方法中添加一些例程来防止优化。您还应该将方法实现从类移动到它的头或源,因为在类的主体中定义方法会隐式地使该方法成为内联的候选方法。gdb不会破坏内联方法,因为它们通常没有可以添加的定义。

#1


4  

Can gdb break on implicit class methods?

gdb可以在隐式类方法上中断吗?

Yes, of course, it can.

是的,当然可以。

(gdb) break MyClass::MyClass(const MyClass &)     // break when copied
(gdb) break MyClass::~MyClass()                   // break when object destroyed

as simple as that. These are breakpoints based, NOT on file:line, but on function names. If you've a namespace wrapping the class then make sure you give the fully qualified name for it e.g.

那么简单。这些是基于断点的,不是基于file:line,而是基于函数名。如果您有一个名称空间包装类,那么请确保为它提供完全限定的名称,例如。

(gdb) break NyNamespace::MyClass::MyClass(const MyClass &)

Look here for a list of ways to specify breakpoints in GDB.

在这里寻找在GDB中指定断点的方法列表。

#2


1  

gdb can break on anything that is either mentioned in the debuginfo or as an ELF sybmol. Offhand I do not know whether your compiler emits debuginfo for these artificial methods.

gdb可以破坏debuginfo中提到的任何内容,或者作为一个ELF sybmol。我不知道您的编译器是否会为这些人工方法发出debuginfo。

#3


0  

I have similar needs, I built my code with

我有类似的需求,我用它来构建代码

g++ main.cpp -std=c++1y -o app_name -g -ggdb

but gdb can't see my implict constructors and assignment operators symbols. And for this reason it don't break on them. Because of that I've used this hack to be able to break on implicitly defined methods of examined class: just implement your own class with explicitly defined methods you're interesting in. Then add this new class object as data member of class you want to debug. Set breakpoints on methods of new class. Enjoy!

但是gdb看不到隐含构造函数和赋值运算符的符号。因为这个原因,它不会断裂。正因为如此,我使用了这一技巧来突破已检查类的隐式定义方法:只需使用感兴趣的显式定义方法实现您自己的类。然后将这个新的类对象添加为要调试的类的数据成员。在新类的方法上设置断点。享受吧!

Example:

例子:

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;
}

Output sample:

输出样例:

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

Important! If you make your methods empty, like:

重要!如果你的方法是空的,比如:

LifeCycleInspector( const LifeCycleInspector& )
{   
}

- your compiler optimization may do fancy things and your debug output may be pretty strange. In this case you may add some routine to the methods to prevent optimization. Also you should move methods implementation from class to its header or source, as defining method right in class's body is implicitly making this method an candidate for inlining. gdb will not break on inlined methods because they usually have no definition which could be adressed.

-你的编译器优化可能会做一些奇特的事情,你的调试输出可能会很奇怪。在这种情况下,您可以在方法中添加一些例程来防止优化。您还应该将方法实现从类移动到它的头或源,因为在类的主体中定义方法会隐式地使该方法成为内联的候选方法。gdb不会破坏内联方法,因为它们通常没有可以添加的定义。