获取函数调用堆栈

int backtrace(void **buffer,int size)

该函数用于获取当前线程的调用堆栈,获取的信息将会被存放在buffer中,它是一个指针列表。参数 size 用来指定buffer中可以保存多少个void* 元素。函数返回值是实际获取的指针个数,最大不超过size大小。

在buffer中的指针实际是从堆栈中获取的返回地址,每一个堆栈框架有一个返回地址。

注意:某些编译器的优化选项对获取正确的调用堆栈有干扰,另外内联函数没有堆栈框架;删除框架指针也会导致无法正确解析堆栈内容。

1. 代码:

#include <stdio.h>                                          
#include <stdlib.h>
#include <stddef.h>
#include <execinfo.h>
#include <signal.h>


void dump(int signo)
{
    void *buffer[30] = {0};
    size_t size;
    char **strings = NULL;
    size_t i = 0;

    size = backtrace(buffer, 30);
    fprintf(stdout, "Obtained %zd stack frames.nm\n", size);

    strings = backtrace_symbols(buffer, size);
    if (strings == NULL)
    {
        perror("backtrace_symbols.");
        exit(EXIT_FAILURE);
    }

    for (i = 0; i < size; i++)
    {
        fprintf(stdout, "%s\n", strings[i]);
    }

    free(strings);
    strings = NULL;

    exit(0);
}


void func_c()
{
    *((volatile char *)0x0) = 0x9999;
}

void func_b()
{
    func_c();
}

void func_a()
{
    func_b();
}


int main(int argc, const char *argv[])
{
    if (signal(SIGSEGV, dump) == SIG_ERR)
        perror("can't catch SIGSEGV");
   
    func_a();
   
    return 0;
}

 

2. 编译

gcc -g -rdynamic fun_trace.c -o test

3. 运行

[baoliw@AONTFN07 test]$ ./test
Obtained 7 stack frames.nm
./test(dump+0x45) [0x80487a9]
[0x6ff400]
./test(func_b+0x8) [0x804886c]
./test(func_a+0x8) [0x8048876]
./test(main+0x33) [0x80488ab]
/lib/libc.so.6(__libc_start_main+0xe6) [0x126cc6]
./test() [0x80486d1]
发布了170 篇原创文章 · 获赞 116 · 访问量 33万+

猜你喜欢

转载自blog.csdn.net/u012247418/article/details/104180031