您的位置:首页 > 产品设计 > UI/UE

使用__builtin_return_address获得程序运行栈情况

2013-11-26 15:42 302 查看
项目中遇到了一个多线程的问题,系统总是莫名其妙的崩溃,而且bug不可重现,后来发现是接收到某些信号的问题,于是乎就加入了信号处理函数,想获得是什么地方触发了这个信号,因为感觉多线程调试比较麻烦,于是就想到了使用利用__builtin_return_address来获得函数运行栈的方法。

直接上测试代码:

 #include <stdio.h>

#include <stdlib.h>

#include <signal.h>

#define MAX_LEVEL 4

void sigfunc(int signo)

{

    printf("%s(0): %p\n", __func__, __builtin_return_address(0));

    printf("%s(1): %p\n", __func__, __builtin_return_address(1));

    printf("%s(2): %p\n", __func__, __builtin_return_address(2));

    printf("%s(3): %p\n", __func__, __builtin_return_address(3));

    printf("%s(4): %p\n", __func__, __builtin_return_address(4));

    exit(1);

}

int b()

{

    printf("%s(0): %p\n", __func__, __builtin_return_address(0));

    while(1)

    {

        sleep(1);

    }

}

int a(int temp)

{

    temp += 1;

    printf("%s(0): %p\n", __func__, __builtin_return_address(0));

    b();

    return temp;

}

int main()

{

    signal(SIGINT, sigfunc);

    a(123);

    return 0;

}
运行结果:

wangyao@wangyao-laptop:~/Test$ ./a.out

a(0): 0x8048554

b(0): 0x804851e

sigfunc(0): 0xb7eef420

sigfunc(1): 0x80484f2

sigfunc(2): 0x804851e

sigfunc(3): 0x8048554

sigfunc(4): 0xb7da2450

我们已经拿到了程序运行轨迹中的逻辑地址,下面的就是在gdb里面l一下那些地址就可以了:

wangyao@wangyao-laptop:~/Test$ gdb -q a.out

(gdb) l *0x804851e

0x804851e is in a (t_return.c:37).

32        temp += 1;

33        printf("%s(0): %p\n", __func__, __builtin_return_address(0));

34   

35        b();

36   
37        return temp;

38    }

39   

40    int main()

41    {

(gdb) q

这样就已经找到了程序运行的轨迹,如果使用一些ELF处理的库直接解析符号表的话,也可以不用gdb来做,直接通过得到的逻辑地址进行定位;-)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: