2013-12-17 22 views
2

我正在为一家小型软件公司工作,该公司正在制作Windows应用程序,并且该公司开发的IDE缺少对Valgrind或C运行时调试库的支持。我们已经为C编写了一个基本的内存泄漏检测程序,它通过在main()退出并检查一个链接列表(用于记录内存分配和释放内存)之前设置一个断点来处理未实现的内存。我们希望添加C++支持,但是由于内存释放可能在main()在全局变量的析构函数内返回之后发生,因此在main的末尾添加断点不再有效。使用gdb,可以在静态对象销毁后添加断点吗?

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

回答

1

C++静态对象被破坏exit()。您可以在_exit()上放置一个断点,此时所有静态对象都必须被破坏。

请参阅回溯在Linux上的测试程序和сlang++编译:

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()和th调用了_exit()。因此,在_ exit()上放置一个断点,并检查链接列表。如果我理解正确,你的链表必须是一个全局变量。

+0

GDB似乎无法找到_exit函数。这是一个Linux特定的事情吗?如果是,是否有Windows相同?谢谢。 – user3109672

+0

它不是Linux专用的:http://pubs.opengroup.org/onlinepubs/009695399/functions/exit.html –

相关问题