在Linux程序中输出函数调用栈

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

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运行程序,输出如下:

Dump stack with backtrace

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值