作用:
在一个函数调用栈中,输出 backtrace()函数返回时需要执行的下一条指令的地址,以及返回主调函数后的下一条指令的地址,递归上一步,直到从系统中链接进来的 _start() 为止。
1,示例先行
hello_glibc.c :
#include <stdlib.h>
#include <stdio.h>
#include <execinfo.h>
#define BACKTRACE_SIZ 64
void do_backtrace()
{
void *array[BACKTRACE_SIZ];
size_t size, i;
char **strings;
size = backtrace(array, BACKTRACE_SIZ);
strings = backtrace_symbols(array, size);
for(i=0; i<size; i++)
{
printf("%p: %s\n", array[i], strings[i]);
}
free(strings);
}
void aaa(){
do_backtrace();
}
void bbb()
{
aaa();
}
void ccc()
{
bbb();
}
int main()
{
ccc();
return 0;
}
2, 编译执行
$ gcc ./hello_glibc.c -rdynamic -g
上图中每一行的格式:
下一条指令的地址: 指令所在文件名(主调函数名 + 主调函数地址相对下一条指令的offset)[下一条指令的地址]
3,数量关系分析
对比于上一张图,除了relocation 加上的基址,可以看出aaa+0x12中的
0x12 是返回地址相对于函数aaa起始地址的偏移量 0x12个字节