【问题标题】:With gdb, can a breakpoint be added after static object destruction?用gdb,静态对象销毁后可以加断点吗?
【发布时间】:2014-01-04 17:41:39
【问题描述】:

我在一家小型软件公司工作,该公司使用该公司开发的 IDE 和 IDE 制作 Windows 应用程序,该公司缺乏对 Valgrind 或 C 运行时调试库的支持。我们为 C 编写了一个原始的内存泄漏检测程序,它通过在 main() 退出之前设置一个断点并检查一个链表(它跟踪内存分配和释放)来查找未释放的内存。我们希望添加 C++ 支持,但由于内存释放可能在 main() 在全局变量的析构函数中返回后发生,因此在 main 末尾添加断点不再有效。

所以我想知道是否有办法在静态对象销毁后添加断点?顺便说一下,我们使用的编译器是 Clang。

【问题讨论】:

    标签: c++ memory-leaks gdb destructor breakpoints


    【解决方案1】:

    C++ 静态对象在exit() 中被破坏。您可以在_exit() 上设置断点,此时必须销毁所有静态对象。

    请查看使用 сlang++ 编译的 Linux 测试程序中的回溯:

    struct C {
      C() :
        ptr (new int)
      {
      }
    
      ~C()
      {
        delete ptr;
      }
      int *ptr;
    };
    
    C c;
    
    int main()
    {
      return 0;
    }
    

    这是一个 gdb 脚本:

    set breakpoint pending on
    b _exit
    command
    bt
    c
    end
    
    b C::~C
    command
    bt
    c
    end
    
    b free
    command
    bt
    c
    end
    
    r
    

    这本身就是一个测试:

    gdb -q -x test.gdb  ./a.out
    Reading symbols from /import/home/sergey.kurenkov/src/linux.x64.6.0/tests/test.break_after_static/a.out...done.
    Function "_exit" not defined.
    Breakpoint 1 (_exit) pending.
    Breakpoint 2 at 0x400680: C::~C. (2 locations)
    Function "free" not defined.
    Breakpoint 3 (free) pending.
    
    Breakpoint 2, C::~C (this=0x600be8 <c>) at main.cpp:8
    8         {
    #0  C::~C (this=0x600be8 <c>) at main.cpp:8
    #1  0x0000003c41235db2 in exit () from /lib64/libc.so.6
    #2  0x0000003c4121ece4 in __libc_start_main () from /lib64/libc.so.6
    #3  0x0000000000400519 in _start ()
    
    Breakpoint 2, C::~C (this=0x600be8 <c>) at main.cpp:9
    9           delete ptr;
    #0  C::~C (this=0x600be8 <c>) at main.cpp:9
    #1  0x0000000000400685 in C::~C (this=0x600be8 <c>) at main.cpp:8
    #2  0x0000003c41235db2 in exit () from /lib64/libc.so.6
    #3  0x0000003c4121ece4 in __libc_start_main () from /lib64/libc.so.6
    #4  0x0000000000400519 in _start ()
    
    Breakpoint 3, 0x0000003c4127a950 in free () from /lib64/libc.so.6
    #0  0x0000003c4127a950 in free () from /lib64/libc.so.6
    #1  0x00000000004006c0 in C::~C (this=0x600be8 <c>) at main.cpp:9
    #2  0x0000000000400685 in C::~C (this=0x600be8 <c>) at main.cpp:8
    #3  0x0000003c41235db2 in exit () from /lib64/libc.so.6
    #4  0x0000003c4121ece4 in __libc_start_main () from /lib64/libc.so.6
    #5  0x0000000000400519 in _start ()
    
    Breakpoint 1, 0x0000003c412abc30 in _exit () from /lib64/libc.so.6
    #0  0x0000003c412abc30 in _exit () from /lib64/libc.so.6
    #1  0x0000003c41235d62 in exit () from /lib64/libc.so.6
    #2  0x0000003c4121ece4 in __libc_start_main () from /lib64/libc.so.6
    #3  0x0000000000400519 in _start ()
    [Inferior 1 (process 13558) exited normally]
    (gdb)
    

    如你所见,C::~C() 在exit() 中被调用,C::~C() 本身调用free() 然后_exit() 被调用。因此,在 _exit() 上放置一个断点,并在执行此操作时检查您的链表。如果我理解正确,您的链接列表必须是全局变量。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    • 2019-11-10
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    • 2019-03-17
    • 2015-01-13
    相关资源
    最近更新 更多