#include <csapp.h>
#define STACK_SIZE 32
void static printStack();
void fun1();
void fun2();
void fun3();
void print_stack();
int main()
{
//atexit(printStack);
fun3();
return;
}
void fun1()
{
printf("print_fun1\n");
print_stack();
//printStack();
}
void fun2()
{
printf("print_fun2\n");
fun1();
}
void fun3()
{
printf("print_fun3\n");
fun2();
}
void print_stack()
{
int size = 16;
int i;
void *array[16];
int stack_num = backtrace(array, size);
char **stacktrace = NULL;
stacktrace = (char**)backtrace_symbols(array, stack_num);
for(i = 0; i < stack_num; i++)
{
printf("%d----->%s\n",i, stacktrace[i]);
}
free(stacktrace);
}
void static printStack(void)
{
void *trace[STACK_SIZE];
size_t size = backtrace(trace, STACK_SIZE);
char **symbols = (char **)backtrace_symbols(trace,size);
size_t i = 0;
for(; i<size; i++)
{
printf("%d--->%s\n", i, symbols[i]);
}
return;
}
接下来使用下面这条命令编译:
gcc -o testexit testexit.c -g -lpthread -rdynamic
重点是添加-rdynamic
否者结果是这样的:
[root@host-192-0-11-183 csapp]# ./testexit
print_fun3
print_fun2
print_fun1
0----->./testexit() [0x402f05]
1----->./testexit() [0x402ea4]
2----->./testexit() [0x402ebe]
3----->./testexit() [0x402ed8]
4----->./testexit() [0x402e89]
5----->/lib64/libc.so.6(__libc_start_main+0xf5) [0x7f046bd36c05]
6----->./testexit() [0x401a19]
使用-rdynamic
之后结果如下:
[root@host-192-0-11-183 csapp]# ./testexit
print_fun3
print_fun2
print_fun1
0----->./testexit(print_stack+0x2b) [0x403df5]
1----->./testexit(fun1+0x18) [0x403d94]
2----->./testexit(fun2+0x18) [0x403dae]
3----->./testexit(fun3+0x18) [0x403dc8]
4----->./testexit(main+0xe) [0x403d79]
5----->/lib64/libc.so.6(__libc_start_main+0xf5) [0x7fb95659fc05]
6----->./testexit() [0x402909]
关于-rdynamic
参考下面这篇文章:
https://blog.csdn.net/freeelinux/article/details/52910636
关于exit(),_exit(),return
这三者之间的关系,参看如下几篇文章:
https://blog.csdn.net/kang___xi/article/details/80545510
https://blog.csdn.net/drdairen/article/details/51896141
https://blog.csdn.net/susershine/article/details/17404541
网友评论