如何查看程序的运行栈 之 __builtin_return_address的使用
2014-05-14 21:07
387 查看
针对大型软件中,在调试问题时,经常会发现某些业务逻辑的调用路径很难查找,或者说是不清楚程序的运行栈。
想查看程序的运行栈有几种方法:
(1)程序编译时,带 -g 选项,直接在某个函数(接口)添加一行导致死机的代码,死机堆栈就可以找到程序的运行栈,很龊但是有时候挺管用;
(2)在函数里面添加__builtin_return_address来查找程序的运行栈;
本篇介绍一下的__builtin_return_address函数的使用
__builtin_return_address 函数的作用是返回所在函数被一级函数调用后,退出的地址(通常为return)。
英文原意是“When inlining the expected behavior is that the function returns the address of the function that is returned to”
此处参考网络上一个示例 :
示例代码test_build_return_address.c
编译(gcc -g test_build_return_address.c -o test_build_return_address),运行(gdb -q test_build_return_address)
会打印运行栈的地址:
[root@localhost test]# gdb -q test_build_return_address
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) run
Starting program: /home/kehuanyu/test/test_build_return_address
c(0): 0x8048516
a(0): 0x80484f4
b(0): 0x80484be
接着ctrl+c ,通过gdb指令来找到对应的代码:
Program received signal SIGINT, Interrupt.
0x003d1402 in __kernel_vsyscall ()
(gdb) l *0x80484be
0x80484be is in a (test_build_return_address.c:32).
27 temp += 1;
28 printf("%s(0): %p\n", __func__, __builtin_return_address(0));
29
30 b();
31
32 return temp;
33 }
34
35 int c(int temp)
36 {
(gdb) l *0x80484f4
0x80484f4 is in c (test_build_return_address.c:43).
38
39 printf("%s(0): %p\n", __func__, __builtin_return_address(0));
40
41 a(123);
42
43 return temp;
44 }
45
46 int main()
47 {
(gdb) l *0x8048516
0x8048516 is in main (test_build_return_address.c:51).
46 int main()
47 {
48 // signal(SIGINT, sigfunc);
49 // a(123);
50 c(123);
51 return 0;
52 }
其实获取到运行栈地址之后,也可以通过ELF处理库直接解析符号列表。
友情链接:
http://gcc.gnu.org/onlinedocs/gcc/Return-Address.html 关于函数调用返回信息的__builtin_系列函数
void *__builtin_return_address(unsigned
int level)
void *__builtin_extract_return_addr(void
*addr)
void
*__builtin_frob_return_address(void
*addr)
void
*__builtin_frame_address(unsigned
int level)
http://www.gnu.org/software/gdb/ gdb的使用
https://gcc.gnu.org/ gcc编译器
想查看程序的运行栈有几种方法:
(1)程序编译时,带 -g 选项,直接在某个函数(接口)添加一行导致死机的代码,死机堆栈就可以找到程序的运行栈,很龊但是有时候挺管用;
(2)在函数里面添加__builtin_return_address来查找程序的运行栈;
本篇介绍一下的__builtin_return_address函数的使用
__builtin_return_address 函数的作用是返回所在函数被一级函数调用后,退出的地址(通常为return)。
英文原意是“When inlining the expected behavior is that the function returns the address of the function that is returned to”
此处参考网络上一个示例 :
示例代码test_build_return_address.c
#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 c(int temp) { temp++; printf("%s(0): %p\n", __func__, __builtin_return_address(0)); a(123); return temp; } int main() { // signal(SIGINT, sigfunc); // a(123); c(123); return 0; }
编译(gcc -g test_build_return_address.c -o test_build_return_address),运行(gdb -q test_build_return_address)
会打印运行栈的地址:
[root@localhost test]# gdb -q test_build_return_address
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) run
Starting program: /home/kehuanyu/test/test_build_return_address
c(0): 0x8048516
a(0): 0x80484f4
b(0): 0x80484be
接着ctrl+c ,通过gdb指令来找到对应的代码:
Program received signal SIGINT, Interrupt.
0x003d1402 in __kernel_vsyscall ()
(gdb) l *0x80484be
0x80484be is in a (test_build_return_address.c:32).
27 temp += 1;
28 printf("%s(0): %p\n", __func__, __builtin_return_address(0));
29
30 b();
31
32 return temp;
33 }
34
35 int c(int temp)
36 {
(gdb) l *0x80484f4
0x80484f4 is in c (test_build_return_address.c:43).
38
39 printf("%s(0): %p\n", __func__, __builtin_return_address(0));
40
41 a(123);
42
43 return temp;
44 }
45
46 int main()
47 {
(gdb) l *0x8048516
0x8048516 is in main (test_build_return_address.c:51).
46 int main()
47 {
48 // signal(SIGINT, sigfunc);
49 // a(123);
50 c(123);
51 return 0;
52 }
其实获取到运行栈地址之后,也可以通过ELF处理库直接解析符号列表。
友情链接:
http://gcc.gnu.org/onlinedocs/gcc/Return-Address.html 关于函数调用返回信息的__builtin_系列函数
void *__builtin_return_address(unsigned
int level)
void *__builtin_extract_return_addr(void
*addr)
void
*__builtin_frob_return_address(void
*addr)
void
*__builtin_frame_address(unsigned
int level)
http://www.gnu.org/software/gdb/ gdb的使用
https://gcc.gnu.org/ gcc编译器
相关文章推荐
- 使用__builtin_return_address获得程序运行栈情况
- 使用__builtin_return_address获得程序运行栈情况
- 用__builtin_return_address获得程序运行栈情况【转】
- 如何查看Linux系统下程序运行时使用的库?
- 用__builtin_return_address获得程序运行栈情况
- 将gcc下的程序移植到MSVC下 之二 - __builtin_return_address的实现
- 如何查看自己程序中正在运行的Graph?
- at 命令来安排命令、脚本或程序在指定的日期和时间运行。您也可以使用此命令查看现有的计划任务。
- 如何利用windosAPI计算程序运行时间 不使用VC的库,也就是说不跨系统,跨编译器
- 如何使用Administrators组用户运行ASP程序
- 如何查看哪个程序正在使用80端口
- Vista、Win7上.net程序如何自动使用管理员权限运行
- 如何查看iOS程序运行时所占的内存大小
- 如何在运行时切换WinForm程序使用的语言?
- 如何查看哪个程序在使用80端口
- 查看程序运行时间,gprof使用详细介绍
- 如何查看系统正在使用的端口号和对应的程序
- C#使用_如何在没有装VS(Visual Studio)的机器上编译运行C#程序
- 如何使PC上运行的程序不能退出,并且用户只能使用当前正在运行的程序。不能使用PC上的其他程序
- 查看程序运行时间, gprof使用详细介绍