用backtrace打印函数栈信息

Linux的应用程序在core dump之后,内核会把该应该程序当前的内存信息dump出来,解开core文件以后可以看到函数的调用栈。那么如果没有core dump,可以看到函数的调用栈吗?当然可以了,Linux提供了相关了系统调用backtrace和backtrace_symbols。注意这两个系统调用跟具体的体系架构有关,在x86上支持的是最好的,如果是其他的系统架构则要小心一些。看一段简单的代码。

 

#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>

void printtrace(void)
{
  void *array[10];
  int size, i;
  char **strings;

  size = backtrace(array,10);
  strings = backtrace_symbols(array, size);

  printf("Obtain the %d stack frame.\n", size);

  for(i = 0; i < size; i++)
  {
    printf("%s\n", strings[i]);
  }
  free(strings);
}

void dummy(void)
{
  printtrace();
}

int main(void)
{
  dummy();
  return 0;
}

执行结果如下:

Obtain the 5 stack frame.
./back() [0x80484f9]
./back() [0x804856a]
./back() [0x8048577]
/lib/libc.so.6(__libc_start_main+0xf5) [0x4290f635]
./back() [0x8048401]

只能看到函数地址,看不到函数名咋办?简单用addr2line

addr2line 0x804856a -e back -f

dummy
/tmp/test/back.c:26

我们再看一下back的elf信息

readelf -S ./back
There are 35 section headers, starting at offset 0xd04:

Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .interp PROGBITS 08048134 000134 000013 00 A 0 0 1
[ 2] .note.ABI-tag NOTE 08048148 000148 000020 00 A 0 0 4
[ 3] .note.gnu.build-i NOTE 08048168 000168 000024 00 A 0 0 4
[ 4] .gnu.hash GNU_HASH 0804818c 00018c 000020 04 A 5 0 4
[ 5] .dynsym DYNSYM 080481ac 0001ac 000090 10 A 6 1 4
[ 6] .dynstr STRTAB 0804823c 00023c 00007c 00 A 0 0 1
[ 7] .gnu.version VERSYM 080482b8 0002b8 000012 02 A 5 0 2
[ 8] .gnu.version_r VERNEED 080482cc 0002cc 000030 00 A 6 1 4
[ 9] .rel.dyn REL 080482fc 0002fc 000008 08 A 5 0 4
[10] .rel.plt REL 08048304 000304 000038 08 A 5 12 4
[11] .init PROGBITS 0804833c 00033c 000023 00 AX 0 0 4
[12] .plt PROGBITS 08048360 000360 000080 04 AX 0 0 16
[13] .text PROGBITS 080483e0 0003e0 000214 00 AX 0 0 16
[14] .fini PROGBITS 080485f4 0005f4 000014 00 AX 0 0 4
[15] .rodata PROGBITS 08048608 000608 000028 00 A 0 0 4
[16] .eh_frame_hdr PROGBITS 08048630 000630 00003c 00 A 0 0 4
[17] .eh_frame PROGBITS 0804866c 00066c 0000f0 00 A 0 0 4
[18] .init_array INIT_ARRAY 0804975c 00075c 000004 00 WA 0 0 4
[19] .fini_array FINI_ARRAY 08049760 000760 000004 00 WA 0 0 4
[20] .jcr PROGBITS 08049764 000764 000004 00 WA 0 0 4
[21] .dynamic DYNAMIC 08049768 000768 0000e8 08 WA 6 0 4
[22] .got PROGBITS 08049850 000850 000004 04 WA 0 0 4
[23] .got.plt PROGBITS 08049854 000854 000028 04 WA 0 0 4
[24] .data PROGBITS 0804987c 00087c 000004 00 WA 0 0 4
[25] .bss NOBITS 08049880 000880 000004 00 WA 0 0 4
[26] .comment PROGBITS 00000000 000880 00002c 01 MS 0 0 1
[27] .debug_aranges PROGBITS 00000000 0008ac 000020 00 0 0 1
[28] .debug_info PROGBITS 00000000 0008cc 00010b 00 0 0 1
[29] .debug_abbrev PROGBITS 00000000 0009d7 0000b6 00 0 0 1
[30] .debug_line PROGBITS 00000000 000a8d 000056 00 0 0 1
[31] .debug_str PROGBITS 00000000 000ae3 0000d8 01 MS 0 0 1
[32] .shstrtab STRTAB 00000000 000bbb 000146 00 0 0 1
[33] .symtab SYMTAB 00000000 00127c 0004d0 10 34 49 4
[34] .strtab STRTAB 00000000 00174c 0002b4 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)

看到代码段的初始地址是0x080483e0,size是0x214,那么结束的地址就是0x080485F4。函数的地址都在这个范围内。

转载于:https://www.cnblogs.com/CalvinWang/p/5465748.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值