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 100 void print_backtrace()
{
void* buffer[BACKTRACE_SIZE]={};
int pointer_num = backtrace(buffer, BACKTRACE_SIZE);
char** string_buffer = backtrace_symbols(buffer, pointer_num);
if(string_buffer == NULL)
{
printf("backtrace_symbols error");
exit(-);
} printf("print backtrace begin\n");
for(int i = ; 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 > )
{
func(--num);
}
else
{
print_backtrace();
}
} int main(int argc, char* argv[])
{
if(argc != )
{
printf("input param error");
return -;
} int input_num = atoi(argv[]);
func(input_num); return ;
}

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

backtrace函数的更多相关文章

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

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

  2. 利用backtrace和backtrace_symbols函数打印调用栈信息

    在头文件"execinfo.h"中声明了三个函数用于获取当前线程的函数调用堆栈. #include <execinfo.h>  int backtrace(void * ...

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

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

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

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

  5. 用户态使用 glibc/backtrace 追踪函数调用堆栈定位段错误【转】

    转自:https://blog.csdn.net/gatieme/article/details/84189280 版权声明:本文为博主原创文章 && 转载请著名出处 @ http:/ ...

  6. 高效获得Linux函数调用栈/backtrace的方法【转】

    转自:https://blog.csdn.net/littlefang/article/details/42295803 有四种方法可以获得Linux的函数调用堆栈,参见CALL STACK TRAC ...

  7. backtrace和backtrace_symbols

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

  8. objdump和backtrace的配合使用

    在程序调试过程中程序崩溃的情况时有发生,把出问题时的调用栈信息打印出来是一种不错的解决办法. 当然还有一些其他方法:https://www.cnblogs.com/jiangyibo/p/865372 ...

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

    来源:Linux社区  作者:astrotycoon 一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序 ...

随机推荐

  1. 深入浅出 关于SQL Server中的死锁问题

    深入浅出 关于SQL Server中的死锁问题 博客2013-02-12 13:44   分享到:我要吐槽 死锁的本质是一种僵持状态,是多个主体对于资源的争用而导致的.理解死锁首先需要对死锁所涉及的相 ...

  2. ANT 的Table表格样式修改方法

    注:(大家在给页面添加参数或者方法的时候,记得写上注释,方便别人查看) 1.表格行选中样式添加:(可以去beijing,精子库质控统计查看例子) (咱们以前页面上的表格都是在hover时显示选中效果, ...

  3. 在同一网关下ping不通其他电脑

    最近在做数据库相关的程序,所以想先用ping试下和主机连没连着,但发现虽然两台电脑在同一网关下,但却互相ping不通,后来才发现,原来是防火墙在作怪. Omg!感慨一下!默认的情况下,保守的windo ...

  4. 如何查找Fiori UI上某个字段对应的后台存储表的名称

    今天微信群里有朋友问到这个问题. 如果是SAPGUI里的事务码,比如MM01,对于开发者来说这个任务非常容易完成. 比如我想知道下图"Sales Unit"这个字段的值到底保存在哪 ...

  5. MySQL学习(四)查询

    一.group_concat()函数.把groupby的分组中字段数据组合显示出来 select s_id , GROUP_CONCAT(要显示的字段名)  from table group by 分 ...

  6. python 提取字符串中的数字组成新的字符串

    方法一 # 有一个字符串text = "aAsmr3idd4bgs7Dlsf9eAF" # 请将text字符串中的数字取出,并输出成一个新的字符串 import re text = ...

  7. Android(java)学习笔记17:网络编程的概述

    1. 计算机网络 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统 ...

  8. Jupyter notebook 的一个问题

    Traceback (most recent call last): File , in get value = obj._trait_values[self.name] KeyError: 'all ...

  9. PIL 一秒切九图 朋友圈发图神器

    注意图片像素返回值是(宽度,高度),pil填像素点坐标原点左上角. 判断像素点是否在圆方程中. import numpy as np from PIL import Image file = inpu ...

  10. HDU 3336 KMP

    题意:求每一个前缀,跟前缀相同的每个子串. 此题:网上很多都是假程序,不过也AC了,的确我测试几个案例之后的的确确是存在这个问题. 分析:每一个前缀,可以考虑KMP,f失配指针,如何求得它出现了多少次 ...