您的位置首页>企业动态>

linux中追踪函数backtrace调用堆栈

导读大家好,我是极客范的本期栏目编辑小友,现在为大家讲解linux中追踪函数backtrace调用堆栈问题。通常,查看函数运行时堆栈的方法是使用外部

音频解说

大家好,我是极客范的本期栏目编辑小友,现在为大家讲解linux中追踪函数backtrace调用堆栈问题。

通常,查看函数运行时堆栈的方法是使用外部调试器,如GDB。但是有时候为了分析程序的bug(主要是针对长时间运行的程序的分析),在程序出错的时候把函数的调用栈打印出来是非常有用的。在头文件‘exec info . h’中,声明了三个函数来获取当前线程的函数调用栈,Function : int back trace(void * * buffer,int size)。该函数用于获取当前线程的调用栈,获取的信息将存储在缓冲区中,缓冲区是一个指针列表。参数大小用于指定缓冲区中可以保存多少void*元素。函数的返回值是实际得到的指针数,最大值不超过大小。缓冲区中的指针实际上是从堆栈中获得的返回地址。每个堆栈帧都有一个返回地址。请注意,一些编译器优化选项会干扰获取正确的调用堆栈,并且没有用于内联函数的堆栈框架。删除帧指针也将无法正确解析堆栈内容函数: char * * backtrace _ symbols(void * const * buffer,Int size)backtrace_symbols将从back trace函数获得的信息转换为字符串数组。参数缓冲区应该是从backtrace函数获得的数组指针,大小是数组中的元素个数(backtrace的返回值)。函数的返回值是指向字符串数组的指针。它的大小与缓冲区的大小相同。每个字符串都包含与缓冲区中相应元素相关的可打印信息。它包括函数名、函数的偏移地址和实际返回地址。现在只有ELF二进制格式的程序和程序才能得到函数名和偏移量地址。在其他系统中,只能获得十六进制返回地址。此外,您可能需要将相应的标志传递给链接器。要支持函数名函数(比如在使用GNU ld的系统中,需要传递(-rddynamic)),这个函数的返回值就是malloc函数申请的空间,所以调用这个的时候必须使用free函数来释放指针。注意:如果不能为字符串获取足够的空间,函数的返回值将为null函数3360 void backtrace _ symbols _ FD(void * const * buffer,int size,Int fd)backtrace_symbols_fd的函数与back trace _ symbols函数相同,只是它没有向调用者返回字符串数组,而是将结果写入一个带有FD文件描述符的文件中,每个函数对应一行。它不需要调用malloc函数,所以适合调用这个函数可能失败的情况。以下示例显示了这三个函数的用法。

# include exec info . h # include stdio . h # include stdlib . hvoid print _ trace(void){ void * array[10];size_t大小;char * *字符串;size _ t I;size=backtrace(数组,10);strings=backtrace_symbols(数组,大小);printf('已获得%zd堆栈帧。/n ',大小);for(I=0;一、尺寸;I)printf(“% s/n”,字符串);自由(字符串);}void dummy _ function(void){ print _ trace();} int main(void){ dummy _ function();返回0;}

注意:void *const *buffer - buffer的缓冲区指针指向char类型的const指针(非常笨拙)

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。