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]