Linux C语言打印函数调用栈

2023-10-15  本文已影响0人  CodingCode

代码例子:

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

void print_trace()
{
    int MAX_STACK_LEVELS=50;
    void *buffer[MAX_STACK_LEVELS];
    int levels = backtrace(buffer, MAX_STACK_LEVELS);

    int fd = -1;
    if (fd != -1) {
        int i;
        char **strings = backtrace_symbols (buffer, levels);
        if (strings != NULL) {
            for (i = 1; i < levels; i++) {  // start from 1 to skip the print_trace itself
                printf ("%s\n", strings[i]);
            }
            free (strings);
        }

    } else {
        backtrace_symbols_fd(buffer + 1, levels - 1, 2);    // skip the print_trace itself
    }
}

void foo3(void)
{
    print_trace();
}

void foo2(void)
{
    foo3();
}

void foo1(void)
{
    foo2();
}

int main (void)
{
    foo1();
    return 0;
}

编译运行:

$ gcc -rdynamic test.c
$ ./a.out
./a.out(foo3+0xe)[0x4009f9]
./a.out(foo2+0x9)[0x400a04]
./a.out(foo1+0x9)[0x400a0f]
./a.out(main+0x9)[0x400a1a]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7f61a25b6555]
./a.out[0x400809]

注意这里编译一定要带上-rdynamic参数:

       -rdynamic
           Pass the flag -export-dynamic to the ELF linker, on targets that support it. This instructs the linker to add all
           symbols, not only used ones, to the dynamic symbol table. This option is needed for some uses of "dlopen" or to
           allow obtaining backtraces from within a program.

因为否则,拿不到函数符号表信息:

$ gcc test.c
$ ./a.out
./a.out[0x400799]
./a.out[0x4007a4]
./a.out[0x4007af]
./a.out[0x4007ba]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7fb2a46af555]
./a.out[0x4005a9]
上一篇 下一篇

猜你喜欢

热点阅读