backtrace函数
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函数的更多相关文章
- LiteOS调测利器:backtrace函数原理知多少
摘要:本文将会和读者分享LiteOS 5.0版本中Cortex-M架构的backtrace软件原理及实现,供大家参考和学习交流. 原理介绍 汇编指令的执行流程 图 1 汇编指令的执行顺序 上图1所示, ...
- 利用backtrace和backtrace_symbols函数打印调用栈信息
在头文件"execinfo.h"中声明了三个函数用于获取当前线程的函数调用堆栈. #include <execinfo.h> int backtrace(void * ...
- 嵌入式 linux下利用backtrace追踪函数调用堆栈以及定位段错误
嵌入式 linux下利用backtrace追踪函数调用堆栈以及定位段错误 2015-05-27 14:19 184人阅读 评论(0) 收藏 举报 分类: 嵌入式(928) 一般察看函数运行时堆栈的 ...
- linux下利用backtrace追踪函数调用堆栈以及定位段错误
一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序出错时打印出函数的调用堆栈是非常有用的. 在glibc ...
- 用户态使用 glibc/backtrace 追踪函数调用堆栈定位段错误【转】
转自:https://blog.csdn.net/gatieme/article/details/84189280 版权声明:本文为博主原创文章 && 转载请著名出处 @ http:/ ...
- 高效获得Linux函数调用栈/backtrace的方法【转】
转自:https://blog.csdn.net/littlefang/article/details/42295803 有四种方法可以获得Linux的函数调用堆栈,参见CALL STACK TRAC ...
- backtrace和backtrace_symbols
一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序出错时打印出函数的调用堆栈是非常有用的. 在glibc ...
- objdump和backtrace的配合使用
在程序调试过程中程序崩溃的情况时有发生,把出问题时的调用栈信息打印出来是一种不错的解决办法. 当然还有一些其他方法:https://www.cnblogs.com/jiangyibo/p/865372 ...
- Linux下利用backtrace追踪函数调用堆栈以及定位段错误[转]
来源:Linux社区 作者:astrotycoon 一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序 ...
随机推荐
- Ajax 重构的步骤
Ajax重构大致可以分为以下3三个步骤. 一 创建一个单独的JS文件,名称为AjaxRequest.js,并且在该文件中编写重构Ajax 所需的代码具体代码如下:var net = new Objec ...
- NO.001-2018.02.06《木兰花·拟古决绝词柬友》清代:纳兰性德
木兰花·拟古决绝词柬友原文.翻译及赏析_纳兰性德_古诗文网 木兰花·拟古决绝词柬友 清代:纳兰性德 人生若只如初见,何事秋风悲画扇.与意中人相处应当总像刚刚相识的时候,是那样地甜蜜,那样地温馨,那 ...
- 小组Scrum第一次冲刺
团队任务描述: 在确定完分组,并对于敏捷开发做了相应的了解之后,我们团队开始了第一次的冲刺.对于我们团队的第一次的 Scrum冲刺,我们团队开展了团队会议.首先,我们明确了我们的目标,对其进行了相对初 ...
- poj 2356 抽屉原理
基本原理: n+1个鸽子放到n个笼子里,至少有一个笼子里有两只及其以上的鸽子.若有n个笼子,kn+1个鸽子,至少有一个笼子里面有k+1个鸽子: 题意:给定N个数,挑出一些数,他们和和是n的整数倍: 分 ...
- c#隐藏tabcontrol选项卡
隐藏:Tab1.TabPage2.Parent = null;显示:Tab1.TabPage2.Parent =Tab1;tab1为tab控件名,TabPage2为选项卡名.
- 逻辑回归(分类问题)(Logistic Regression、罗杰斯特回归)
逻辑回归:问题只有两项,即{0, 1}.一般而言,回归问题是连续模型,不用在分类问题上,且噪声较大,但如果非要引入,那么采用逻辑回归模型. 对于一般训练集: 参数系统为: 逻辑回归模型为: ...
- c语言实现数组的转置
#include<stdio.h> int main (){ int i,j,m,n; ][],b[][]; printf("请输入行列式的行数:\n"); scanf ...
- 学大伟业 Day 4 培训总结
今天讲的全是dp... 不多废话,先看一道经典的模板LIS(最长不下降子序列) 一.LIS 给定一个长度为N的数列,求最长上升子序列 例:1 7 2 8 3 4 答案:1 2 3 4 代码: #inc ...
- [LuoguP1141]01迷宫
1141 01迷宫 题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上. 你的任务 ...
- 匿名union
#include <stdio.h> enum node_type{ t_int,t_double}; struct node{ enum node_type type; ...