【问题标题】:gdb breakpoint on base class, but failed基类上的 gdb 断点,但失败
【发布时间】:2013-08-13 07:48:29
【问题描述】:

在mongodb中,类游标定义为'Cursor : boost::noncopyable',然后有很多类是从它派生的。我想知道客户端的给定操作使用了哪个 XXXCursor。所以我想在 Cursor::Cursor 上设置一个断点。但失败了。

(gdb) b mongo::Cursor::Cursor
the class mongo::Cursor does not have any method named Cursor
Hint: try 'mongo::Cursor::Cursor<TAB> or 'mongo::Cursor::Cursor<ESC-?>
(Note leading single quote.)
Make breakpoint pending on future shared library load? (y or [n]) n

(gdb) ptype mongo::Cursor
type = class mongo::Cursor : private boost::noncopyable_::noncopyable {
  public:
    ~Cursor(int);
    virtual bool ok(void);
    bool eof(void);
    virtual mongo::Record * _current(void);
    virtual mongo::BSONObj current(void);
    virtual mongo::DiskLoc currLoc(void);
    virtual bool advance(void);
    virtual mongo::BSONObj currKey(void) const;
    ....
}
(gdb) list mongo::Cursor::Cursor
**the class mongo::Cursor does not have any method named Cursor
Hint: try 'mongo::Cursor::Cursor<TAB> or 'mongo::Cursor::Cursor<ESC-?>**
(Note leading single quote.)

但是我写了一个类似的程序

#include <iostream>
#include <boost/utility.hpp>
class Base : boost::noncopyable {
public:
    void printx() {std::cout<< getx() <<"\n" ;}
    virtual int getx()=0;
};


class P : public Base {
public:
    int x;
    virtual int getx() { return x*3;}
    P(int c){ x= c;}
};

int main(){
    P p(2);
    p.printx();
    return 0;
}

我可以成功地在 Base::Base 上设置断点。

你知道为什么我不能在 mongo::Cursor::Cursor 上设置断点吗?

mongo::Cursor 在这里定义:https://github.com/mongodb/mongo/blob/master/src/mongo/db/cursor.h

【问题讨论】:

    标签: mongodb gdb base-class


    【解决方案1】:

    至于你的例子。如果我这样编译:

    g++ -O0 -g -m64 -I ./boost_1_53_0 main.cpp
    

    我可以在Base::Base 上设置断点,我看到Base::Base 是一个符号:

    >nm -C a.out | grep Base::Base
    0000000000400a4e W Base::Base()
    

    如果我像这样编译编译它(优化级别 O2):

    g++ -O2 -g -m64 -I ./boost_1_53_0 main.cpp
    

    我不认为 Base::Base 是一个符号:

    >nm -C a.out | grep Base::Base
    >
    

    而且不能设置断点:

    (gdb) b Base::Base
    the class Base does not have any method named Base
    Hint: try 'Base::Base<TAB> or 'Base::Base<ESC-?>
    

    因此,第一步确保在您的程序或共享库中有 mongo::Cursor::Cursor 作为符号。可以优化出来。

    【讨论】:

    • FWIW - 仅查看“nm”输出是不够的。 gdb 还可以使用 debuginfo 在内联函数上设置断点。为此,您必须深入研究“readelf -wi”输出。副手我不知道这种情况下的问题。有很多可能的事情 - 编译器错误、gdb 错误、模糊的故意行为等。
    • Tom,在这个例子中 Base::Base() 不是由用户定义的。我的观点是 Base::Base() 是由编译器在 O0 级别上隐式定义的,它是空的。在 O2 级别上,编译器完全摆脱了它,因此它不会被内联。
    • 谢谢你们!我用'scons -Q --d all'构建了mongod。我确实看到输出包含-O0。比如:g++ -o build/linux2/d/mongo/db/jsobj.o -c -Wnon-virtual-dtor -Woverloaded-virtual -fPIC -fno-strict-aliasing -ggdb -pthread -Wall -Wsign-compare -Wno -unknown-pragmas -Winvalid-pch -Werror -pipe -O0 -fstack-protector -Wno-unused-function -Wno-deprecated-declarations -fno-builtin-memcmp -DBOOST_ALL_NO_LIB -D_SCONS -DMONGO_EXPOSE_MACROS -DSUPPORT_UTF8 -D_FILE_OFFSET_BITS=64 -DMONGO_HAVE_HEADER_UNISTD_H -DMONGO_HAVE_EXECINFO_BACKTRACE ...src/mongo/db/jsobj.cpp 所以可能有其他原因。
    猜你喜欢
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    • 2012-08-16
    • 2017-07-28
    • 1970-01-01
    • 2011-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多