程序发生异常时,将函数的调用栈打印出来,可以大大提高定位效率。

Linux中提供了三个函数用来获取调用栈:

/* 获取函数调用栈 */
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);

示例代码:
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>

/* 打印调用栈的最大深度 */
#define DUMP_STACK_DEPTH_MAX 16

/* 打印调用栈函数 */
void dump_trace() {
    void *stack_trace[DUMP_STACK_DEPTH_MAX] = {0};
    char **stack_strings = NULL;
    int stack_depth = 0;
    int i = 0;

/* 获取栈中各层调用函数地址 */
    stack_depth = backtrace(stack_trace, DUMP_STACK_DEPTH_MAX);

/* 查找符号表将函数调用地址转换为函数名称 */
    stack_strings = (char **)backtrace_symbols(stack_trace, stack_depth);
    if (NULL == stack_strings) {
        printf(" Memory is not enough while dump Stack Trace! \r\n");
        return;
    }

/* 打印调用栈 */
    printf(" Stack Trace: \r\n");
    for (i = 0; i < stack_depth; ++i) {
        printf(" [%d] %s \r\n", i, stack_strings[i]);
    }

/* 获取函数名称时申请的内存需要自行释放 */
    free(stack_strings);
    stack_strings = NULL;

return;
}

/* 测试函数 2 */
void test_meloner() {
    dump_trace();
    return;
}

/* 测试函数 1 */
void test_hutaow() {
    test_meloner();
    return;
}

/* 主函数 */
int main(int argc, char *argv[]) {
    test_hutaow();
    return 0;
}

源文件下载:链接

编译时需要加上-rdynamic参数,以得到符号名称,像下面这样:

gcc -rdynamic backtrace.c -o backtrace

执行./backtrace运行程序,输出如下:

转载于:https://blog.51cto.com/jeff1573/1665062

在Linux程序中输出函数调用栈相关推荐

  1. linux 函数中打印调用栈

    一.内核中 To print the stack contents and a backtrace to the kernel log, use the #include <linux/kern ...

  2. 【嵌入式】Ubuntu、stm32下的C程序中堆、栈、全局、局部等变量的分配地址

    Ubuntu.stm32下的C程序中堆.栈.全局.局部等变量的分配地址 一.总体介绍 1.栈区(stack) 2.堆区(heap) 3.全局区(静态区) (1).bss段 (2).data段 4.常量 ...

  3. Ubuntu、stm32下的C程序中堆、栈、全局、局部等变量的重温

    一.C程序的内存分配 1.栈区(stack) 由编译器自动分配释放,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 2.堆区(heap) 一般由程序员分配释放,若程序员不释放,程序 ...

  4. STM32对SD卡数据读取和在Ubuntu、stm32下的C程序中堆、栈、全局、局部等变量的分配地址的对比分析

    一.SD卡协议原理 1.SD卡简介 SD存储卡是一种基于半导体快闪记忆器的新一代记忆设备,由于它体积小.数据传输速度快.可热插拔等优良的特性,被广泛地于便携式装置上使用,例如数码相机.平板电脑和多媒体 ...

  5. 如何在系统崩溃时从C++中获取函数调用栈信息?

    这篇文章主要讲述在 Linux 和 Windows 这 2 个平台上,如何用C++ 来捕获函数调用栈里的信息. 一.前言 程序在执行过程中 crash 是非常严重的问题,一般都应该在测试阶段排除掉这些 ...

  6. Ubuntu、stm32下的C程序中堆、栈、全局、局部等变量的分配地址

    目录 一.C程序中的一些变量及内存分配 1.全局变量 2.局部变量 3.内存分配 4.内存段 5.内存管理 二.在Ubuntu和Keil中显示变量地址分配 1.Ubuntu中运行 代码撰写 运行结果 ...

  7. linux kernel中的进程栈

    1.linux中的user mode的进程栈 在thread_info.h中,设置进程栈的大小为16k #define THREAD_SIZE 16384 #define THREAD_START_S ...

  8. 在chrome开发者工具中观察函数调用栈、作用域链、闭包

    在chrome的开发者工具中,通过断点调试,我们能够非常方便的一步一步的观察JavaScript的执行过程,直观感知函数调用栈,作用域链,变量对象,闭包,this等关键信息的变化.因此,断点调试对于快 ...

  9. lolcat :一个在 Linux 终端中输出彩虹特效的命令行工具

    那些相信 Linux 命令行是单调无聊且没有任何乐趣的人们,你们错了,这里有一些有关 Linux 的文章,它们展示着 Linux 是如何的有趣和"淘气" . Linux命令及Lin ...

最新文章

  1. 拉普拉斯平滑处理 Laplace Smoothing
  2. python查题_python 数据库连表查询习题
  3. HarmonyOS之深入解析媒体会话的管理
  4. tomcat的wget链接_Linux(jdk安装tomcat安装nginx安装gcc/wget)
  5. mysql 自定义函数之判断
  6. python环境配置-windows版
  7. 【EWM系列】SAP EWM WCU和Non-SAP系统接口
  8. DB2开发系列之一——基本语法
  9. 分布式:分布式系统的设计
  10. AIDA64内存与缓存测试过了算稳定吗_无需XMP默认3200MHz,十铨 开创者 内存开箱简测...
  11. 这个在线抠图工具,好用又免费,告别Photoshop繁杂操作
  12. 使用AT命令和GPRS无线模块开发(软件)
  13. Java观察者模式例子
  14. 走近 Apple 中国研发团队。
  15. pymongo 基本操作
  16. 不错的软件测试学习网站
  17. php imagick加GD实现gif图换脸动画生成表情包制作功能
  18. 科学计算机计算二进制,科学计算器如何调成二进制计算
  19. 知名人脸搜索引擎惹众怒:仅需一张照片,几秒钟把你扒得底裤不剩
  20. 石溪计算机学校校服,美国纽约州著名高中推荐盘点,总有你想去的!

热门文章

  1. 【转载】防范SQL注入式攻击
  2. 用Flash MX 2004自制调色版和配色组件(一)
  3. MapReduce的自制Writable分组输出及组内排序
  4. JavaScript的一些实用技巧收藏
  5. mysql alter算法_MySQL ALTER语法的运用方法 操作索引和字段
  6. C语言-动态创建二维数组
  7. 【Linux 内核】Linux 内核特性 ( 组织形式 | 进程调度 | 内核线程 | 多平台虚拟内存管理 | 虚拟文件系统 | 内核模块机制 | 定制系统调用 | 网络模块架构 )
  8. 【Android 逆向】ART 脱壳 ( InMemoryDexClassLoader 脱壳 | 加固厂商在 ART 下使用的两种类加载器 | InMemoryDexClassLoader 源码 )
  9. 【Android 逆向】使用 DB Browser 查看并修改 SQLite 数据库 ( 从 Android 应用数据目录中拷贝数据库文件 | 使用 DB Browser 工具查看数据块文件 )
  10. 【EventBus】EventBus 源码解析 ( 注册订阅者总结 | 从封装的数据结构角度分析 EventBus )