1. man backtrace中的内容
1.1 函数
#include
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);
1.2 代码
backtrace的man page中给出如下demo
-
#include <execinfo.h>
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <unistd.h>
-
-
void myfunc3(void)
-
{
-
int j, nptrs;
-
#define SIZE 100
-
void *buffer[100];
-
char **strings;
-
-
nptrs = backtrace(buffer, SIZE);
-
printf("backtrace() returned %d addresses\n", nptrs);
-
-
/* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
-
would produce similar output to the following: */
-
-
strings = backtrace_symbols(buffer, nptrs);
-
if (strings == NULL) {
-
perror("backtrace_symbols");
-
exit(EXIT_FAILURE);
-
}
-
-
for (j = 0; j < nptrs; j++)
-
printf("%s\n", strings[j]);
-
-
free(strings);
-
}
-
-
static void myfunc2(void)
-
{
-
myfunc3();
-
}
-
-
void myfunc(int ncalls)
-
{
-
if (ncalls > 1)
-
myfunc(ncalls - 1);
-
else
-
myfunc2();
-
}
-
-
int main(int argc, char *argv[])
-
{
-
if (argc != 2) {
-
fprintf(stderr, "%s num-calls\n", argv[0]);
-
exit(EXIT_FAILURE);
-
}
-
-
myfunc(atoi(argv[1]));
-
exit(EXIT_SUCCESS);
-
}
1.3编译
-
cong@msi:/tmp$ gcc -g -o prog prog.c
-
cong@msi:/tmp$ ./prog 3
-
backtrace() returned 8 addresses
-
./prog() [0x4007dc]
-
./prog() [0x400895]
-
./prog() [0x4008bc]
-
./prog() [0x4008b5]
-
./prog() [0x4008b5]
-
./prog() [0x400917]
-
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5) [0x7f6dfdf29ec5]
-
./prog() [0x4006f9]
1.3.1 加入-rdynamic
-
cong@msi:/tmp$ gcc -g -o prog prog.c -rdynamic
-
cong@msi:/tmp$ ./prog
-
./prog num-calls
-
cong@msi:/tmp$ ./prog 3
-
backtrace() returned 8 addresses
-
./prog(myfunc3+0x1f) [0x400a7c]
-
./prog() [0x400b35]
-
./prog(myfunc+0x25) [0x400b5c]
-
./prog(myfunc+0x1e) [0x400b55]
-
./prog(myfunc+0x1e) [0x400b55]
-
./prog(main+0x59) [0x400bb7]
-
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5) [0x7fbc840abec5]
-
./prog() [0x400999]
2.1 实现dump_stack
-
#include <execinfo.h>
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <unistd.h>
-
void dump_stack()
-
{
-
int i;
-
int size = 64;
-
void * array[64];
-
int stack_num = backtrace(array, size);
-
char ** stacktrace = backtrace_symbols(array, stack_num);
-
for (i = 0; i < stack_num; ++i)
-
{
-
printf("%s\n", stacktrace[i]);
-
}
-
free(stacktrace);
-
}
-
-
void fun3()
-
{
-
dump_stack();
-
}
-
-
void fun2()
-
{
-
fun3();
-
}
-
-
-
void fun1()
-
{
-
fun2();
-
}
-
-
-
-
int main(int argc, char *argv[])
-
{
-
fun1();
-
exit(EXIT_SUCCESS);
-
}
2.2 编译
gcc -g -o dump dump.c -rdynamic
2.3运行结果
-
cong@msi:/tmp$ ./dump
-
./dump(dump_stack+0x2c) [0x400989]
-
./dump(fun3+0xe) [0x400a12]
-
./dump(fun2+0xe) [0x400a22]
-
./dump(fun1+0xe) [0x400a32]
-
./dump(main+0x19) [0x400a4d]
-
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5) [0x7fa3dac16ec5]
-
./dump() [0x400899]
./dump -->main-->fun1-->fun2-->fun3-->dump_stack
阅读(1765) | 评论(0) | 转发(0) |