通过编程方式获取backtrace

本文转载至:

在用GDB调试器时可以查看所谓的Backtrace,它包含一系列的函数调用信息,用命令backtrace或bt可以在GDB中查看函数调用栈的信息。有些场合没法使用GDB时,则可以用glibc库函数中的一些相关函数来得到backtrace的信息(在头文件execinfo.h中):

// 获取将backstrace信息,将地址存到buffer中。
// 参数size指定buffer的最大值,返回值则是backstrace的实际大小
int backtrace (void **buffer, int size)
 
// 根据buffer指定的地址,返回符号信息。参数size指定返回符号信息的大小
char ** backtrace_symbols (void *const *buffer, int size)
 
// 类似backtrace_symbols()函数,但是不需要malloc空间来存放符号信息,
// 而是将结果写到文件描述符fd所代表的文件中
void backtrace_symbols_fd (void *const *buffer, int size, int fd)


使用函数backtrace_symbols()或者backtrace_symbols_fd()时,需要用-rdynamic编译才能得到正确的符号名,否则只能得到偏移地址。

关于 -rdynamic ,请参考:

`-rdynamic'
     Pass the flag `-export-dynamic' to the ELF linker, on targets that
     support it. This instructs the linker to add all symbols, not only
     used ones, to the dynamic symbol table. This option is needed for
     some uses of `dlopen' or to allow obtaining backtraces from within
     a program.


下面的示例代码应用了backtrace()和backtrace_symbols()函数来打印backtrace的信息:

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

 /* Obtain a backtrace and print it to stdout. */
 void print_trace (void)
 {
   void *array[10];
   size_t size;
   char **strings;
   size_t i;

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

   printf ("Obtained %zd stack frames./n", size);

   for (i = 0; i < size; i++)
      printf ("%s/n", strings[i]);

   free (strings);
 }

 /* A dummy function to make the backtrace more interesting. */
 void dummy_function (void)
 {
   print_trace ();
 }

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


编译运行的结果如下:

# gcc bt.c -rdynamic -o bt
# ./bt
Obtained 5 stack frames.
./bt(print_trace+0x14) [0x80486e4]
./bt(dummy_function+0xb) [0x8048765]
./bt(main+0x15) [0x804877c]
/lib/tls/libc.so.6(__libc_start_main+0xe4) [0x42015574]
./bt(backtrace_symbols+0x31) [0x8048641]

你可以应用这些函数在程序异常退出时打印backtrace或将它保存到某个文件中,用于之后的分析。

更详细的介绍可以参考http://www.linuxjournal.com/article/6391

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值