最近调试程序学到的几个挺有用的函数,分享一下,希望对用C/C++的朋友有所帮助!
调用栈系列
下面是函数原型:
#include "execinfo .h"
int backtrace(void **buffer, int size);
char **backtrace_symbols(void *const *buffer, int size);
void backtrace_symbols_fd(void *const *buffer, int size, int fd);
接下来,对上面三个函数进行介绍:
- backtrace用来获得当前程序的调用栈,把结果存在buffer中。通常,我们用gdb调试程序,设置合适的断点, 停下来之后,用backtrace(bt)命令,就可以看到当前的调用栈。但是,有的时候,用到条件断点的时候, gdb的功能就没有程序本身的强大了,这个时候,可以考虑在程序中调用backtrace函数,来获取调用栈。
- backtrace_symbols把用backtrace获取的调用栈转换成字符串数组,以字符串数组的形式返回, 使用者需要在外面释放返回的字符串数组所占用的内存
-
backtrace_symbols_fd把用backtrace获取的调用栈信息写到fd所指定的文件中
void * __builtin_return_address (unsigned int level)
这个函数用来得到当前函数,或者调用它的函数的返回地址,得到这个地址后, 通过gdb反汇编,便可得到调用函数相关的信息,这也是在应用中获取调用栈的一种方法。
内存分配、释放系列
#include "malloc .h"
size_t malloc_usable_size((void *__ptr));
这个函数的用法是返回调用malloc后实际分配的可用内存的大小。 我们都知道在C++中,operator new()可以重载各种各样的版本,可以传入调用时的相关信息来跟踪内存分配情况, 但是operator delete()却只有两种形式,不能随意重载,尤其是全局的operator delete(),只有一种版本, 这个时候就比较痛苦了,究竟释放了多少内存呢? 这时候malloc_usable_size()这个函数就有用武之地了, 调用它便可以获取当前释放的内存的大小。这里需要注意的是,如果在delete中用了malloc_usable_size来 计算释放的内存大小,那么在new中也请用它来统计开辟的内存,这样才能对应起来。因为在调用malloc时, 很多时候实际分配的内存会比用户申请的要大一些,所以如果两边的统计方法对应不起来的话,统计结果也会有比较大的判别。
这里关于new/delete重载的一些细节我不做说明,之前我写过一篇文章的, 不明白的朋友可以去看一下这篇文章《细说C++中的new与delete》。