c语言程序中有调用关系的,C语言的那些小秘密之函数的调用关系

显示函数的调用关系是调试器的必备功能,如果我们在程序的运行中出现了崩溃的情况,通过函数的调用关系可以快速定位问题的根源,懂得函数调用关系的实现原理也可以扩充自己的知识面,在没有调试器的情况下,我们也可以自己来实现显示函数的调用关系。在我们自己动手写backtrace函数之前,先来看看glibc提供的backtrace函数的使用。代码如下:本文引用地址:http://www.eepw.com.cn/article/270700.htm

#include

#include

#include

#define MAX_LEVEL 4

static void call2()

{

int i = 0;

void* buffer[MAX_LEVEL] = {0};

int size=backtrace(buffer, MAX_LEVEL);

for(i = 0; i < size; i++)

{

printf("called by %p\n", buffer[i]);

}

return;

}

static void call1()

{

call2();

return;

}

static void call()

{

call1();

return;

}

int main(int argc, char* argv[])

{

call();

return 0;

}

在此先讲解下backtrace()函数的使用:

int backtrace(void **buffer,int size)

该函数用来获取当前线程的调用堆栈,获取的信息将会被存放在buffer中,它是一个指针列表。参数 size 用来指定buffer中可以保存多少个void* 元素。函数返回值是实际获取的指针个数,最大不超过size大小,在buffer中的指针实际是从堆栈中获取的返回地址,每一个堆栈框架有一个返回地址。

接下来的任务就是编译运行了。

root@ubuntu:/home/shiyan# gcc -g -Wall sss.c -o p

root@ubuntu:/home/shiyan# ./p

输出结果为:

called by 0x8048440

called by 0x804847d

called by 0x804848a

called by 0x8048497

上面的运行结果就是调用者的地址,看起来还不是那么的直观,我们使用addr2line工具来实现地址到源代码位置的转换。

运行

root@ubuntu:/home/shiyan# ./p |awk '{print "addr2line "$3" -e p"}'>t.sh;. t.sh;rm -f t.sh

输出结果为:

/home/shiyan/sss.c:12

/home/shiyan/sss.c:27

/home/shiyan/sss.c:34

/home/shiyan/sss.c:40

接下来看看在栈中数据的结构。

58230e222111624a150bc2d3ea863474.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值