1、函数原型

#include <execinfo.h>    

int backtrace(void **buffer, int size);

  该函数获取当前线程的调用堆栈,获取的信息将会被存放在buffer中,它是一个指针数组,参数size用来指定buffer中可以保存多少个void*元素。函数的返回值是实际返回的void*元素个数。buffer中的void*元素实际是从堆栈中获取的返回地址。

char **backtrace_symbols(void *const *buffer, int size);

  该函数将backtrace函数获取的信息转化为一个字符串数组,参数buffer是backtrace获取的堆栈指针,size是backtrace返回值。函数返回值是一个指向字符串数组的指针,它包含char*元素个数为size。每个字符串包含了一个相对于buffer中对应元素的可打印信息,包括函数名、函数偏移地址和实际返回地址。

  backtrace_symbols生成的字符串占用的内存是malloc出来的,但是是一次性malloc出来的,释放是只需要一次性释放返回的二级指针即可。

void backtrace_symbols_fd(void *const *buffer, int size, int fd);

  该函数与backtrace_symbols函数功能相同,只是它不会malloc内存,而是将结果写入文件描述符为fd的文件中,每个函数对应一行。该函数可重入。

2、函数使用注意事项

  • backtrace的实现依赖于栈指针(fp寄存器),在gcc编译过程中任何非零的优化等级(-On参数)或加入了栈指针优化参数-fomit-frame-pointer后多将不能正确得到程序栈信息;
  • backtrace_symbols的实现需要符号名称的支持,在gcc编译过程中需要加入-rdynamic参数;
  • 内联函数没有栈帧,它在编译过程中被展开在调用的位置;
  • 尾调用优化(Tail-call Optimization)将复用当前函数栈,而不再生成新的函数栈,这将导致栈信息不能正确被获取。

3、捕获异常信号并打印堆栈

  当程序出现崩溃等异常时,会接收到内核发送给进程的异常信号,进程接收到异常信号后,可以在处理信号的时候将程序的堆栈信息打印出来,以便于程序调试。

4、程序示例:

#include <stdio.h>
#include <execinfo.h>
#include <unistd.h>
#include <stdlib.h>
#define BACKTRACE_SIZE 100void print_backtrace()
{void* buffer[BACKTRACE_SIZE]={0};int pointer_num = backtrace(buffer, BACKTRACE_SIZE);char** string_buffer = backtrace_symbols(buffer, pointer_num);if(string_buffer == NULL){printf("backtrace_symbols error");exit(-1);}printf("print backtrace begin\n");for(int i = 0; i < pointer_num; i++){printf("%s\n", string_buffer[i]);}printf("print backtrace end\n");free(string_buffer);return;
}void func(int num)
{if(num > 0){func(--num);}else{print_backtrace();}
}int main(int argc, char* argv[])
{if(argc != 2){printf("input param error");return -1;}int input_num = atoi(argv[1]);func(input_num);return 0;
}

执行结果如下,注意在编译时带-rdynamic参数

转载于:https://www.cnblogs.com/fangyan5218/p/10686488.html

backtrace函数相关推荐

  1. LiteOS调测利器:backtrace函数原理知多少

    摘要:本文将会和读者分享LiteOS 5.0版本中Cortex-M架构的backtrace软件原理及实现,供大家参考和学习交流. 原理介绍 汇编指令的执行流程 图 1 汇编指令的执行顺序 上图1所示, ...

  2. 使用Backtrace函数打印调用栈 - Debug居家必备

    glibc提供了backtrace这个库函数,可以用来打印call stack.比如我们可以在程序中注册常见的一些signal,比如SIGSEGMENT, SIGPIPE,然后在这些信号的回调函数中, ...

  3. php 打印函数调用栈,利用backtrace和backtrace_symbols函数打印调用栈信息

    本帖最后由 kylin_try 于 2017-2-6 08:41 编辑 在头文件"execinfo.h"中声明了三个函数用于获取当前线程的函数调用堆栈. #include int ...

  4. linux中追踪函数backtrace调用堆栈

    From: http://www.embeddedlinux.org.cn/html/jishuzixun/201211/19-2388.html 一般察看函数运行时堆栈的方法是使用GDB之类的外部调 ...

  5. C++封装一个易用的打印backtrace信息的函数

    C++封装一个易用的打印backtrace信息的函数 1.前言 2.几个需要用到函数 2.1.backtrace函数 2.2.backtrace_symbols函数 2.3.__cxa_demangl ...

  6. linux c 用户态 调试追踪函数 调用堆栈 定位段错误

    一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序出错时打印出函数的调用堆栈是非常有用的. 在glibc ...

  7. 嵌入式 linux下利用backtrace追踪函数调用堆栈以及定位段错误

    嵌入式 linux下利用backtrace追踪函数调用堆栈以及定位段错误 2015-05-27 14:19 184人阅读 评论(0) 收藏 举报  分类: 嵌入式(928)  一般察看函数运行时堆栈的 ...

  8. Linux下利用backtrace追踪函数调用堆栈以及定位段错误

    一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序出错时打印出函数的调用堆栈是非常有用的. 在glibc ...

  9. 引:善用backtrace解决大问题

    一.用途: 主要用于程序异常退出时寻找错误原因 二.功能: 回溯堆栈,简单的说就是可以列出当前函数调用关系 三.原理: 1. 通过对当前堆栈的分析,找到其上层函数在栈中的帧地址,再分析上层函数的堆栈, ...

  10. c语言的那些小秘密pdf下载,C语言的那些小秘密之函数的调用关系.pdf

    C语言的那些小秘密之函数的调用关系.pdf C 语言的那些小秘密之函数的调用关系语言的那些小秘密之函数的调用关系 显示函数的调用关系是调试器的必备功能 如果我们在程序的运行中出现了崩溃的情 况 通过函 ...

最新文章

  1. 安装Ecshop首页出现报错:Only variables should be passed by referen
  2. child_process 子进程
  3. python入门教程书-清华大学出版社-图书详情-《Python快速入门精讲》
  4. go标准库的学习-fmt
  5. cctype,string,vector
  6. 基于 abp vNext 和 .NET Core 开发博客项目 - 集成Hangfire实现定时任务处理
  7. DP(01背包) UESTC 1218 Pick The Sticks (15CCPC C)
  8. 要比惨吗?看看这个女人
  9. SpringBoot 集成 Nacos
  10. C语言case字句有什么作用,switch case 语句的使用规则
  11. 从冷战到深度学习,一文看懂机器翻译发展史
  12. 电脑中的打印驱动程序如何打包_旧驱动程序会教您如何处理笔记本电脑上的黑屏...
  13. 用VC资源动态链接库解决国际化问题
  14. MDK 使用 ST-Link 下载出现 target dll has been cancelled 的错误的解决方法
  15. python用pd.read_csv()方法来读取csv文件,用DataFrame对象.to_csv()方法来保存数据成csv文件
  16. Centos7 配置Socks5代理
  17. IDC评述网:12月上旬全球域名解析服务商Top15
  18. 10 个免费的网络监控工具
  19. linux安装cmake
  20. Hadoop YARN配置(RM与NM)相关参数

热门文章

  1. MongoDB 学习笔记(一)—— 安装入门
  2. x264编码详细文字全过程
  3. 使用存储过程创建datawindow
  4. LINQ to SQL集成到应用程序中需考虑的一些问题
  5. 应用前瞻||强化学习求解车间调度问题的未来
  6. TED如何和压力做朋友(第二天)
  7. 享元模式C++实现(flyweight)
  8. WordPress数据库error establishing a database connection错误
  9. python 绘图sns.distplot
  10. matlab-lsqcurvefit函数 初始值选取