免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: feasword
打印 上一主题 下一主题

[函数] c中如何打印函数调用堆栈? [复制链接]

论坛徽章:
0
11 [报告]
发表于 2007-06-18 16:26 |只看该作者
这问题C版ms讨论了很多次了,info gcc  
__builtin_return_address
__builtin_frame_address
还有一个相关的, info libc
glibc中,
backtrace
backtrace_symbols

论坛徽章:
0
12 [报告]
发表于 2007-06-18 17:45 |只看该作者
傻傻的想,单线程可以放在一个全局变量里面如何?
函数进入,push,
函数退出,pop,

论坛徽章:
0
13 [报告]
发表于 2007-06-19 10:53 |只看该作者
backtrace
backtrace_symbols
试验了一下,好像只能打印出地址,但是有函数名更方便些
在11楼的提示下在网上找了篇文章,自己裁减了一下

  1. //funstack.c
  2. #define _GNU_SOURCE
  3. #include <memory.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <signal.h>
  7. #include <ucontext.h>
  8. #include <dlfcn.h>
  9. #include <execinfo.h>

  10. #if defined(REG_RIP)
  11. # define SIGSEGV_STACK_IA64
  12. # define REGFORMAT "%016lx"
  13. #elif defined(REG_EIP)
  14. # define SIGSEGV_STACK_X86
  15. # define REGFORMAT "%08x"
  16. #else
  17. # define SIGSEGV_STACK_GENERIC
  18. # define REGFORMAT "%x"
  19. #endif

  20. static void signal_segv(int signum, siginfo_t* info, void*ptr) {
  21.         static const char *si_codes[3] = {"", "SEGV_MAPERR", "SEGV_ACCERR"};

  22.         size_t i;
  23.         ucontext_t *ucontext = (ucontext_t*)ptr;

  24. #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
  25.         int f = 0;
  26.         Dl_info dlinfo;
  27.         void **bp = 0;
  28.         void *ip = 0;
  29. #else
  30.         void *bt[20];
  31.         char **strings;
  32.         size_t sz;
  33. #endif

  34. #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
  35. # if defined(SIGSEGV_STACK_IA64)
  36.         ip = (void*)ucontext->uc_mcontext.gregs[REG_RIP];
  37.         bp = (void**)ucontext->uc_mcontext.gregs[REG_RBP];
  38. # elif defined(SIGSEGV_STACK_X86)
  39.         ip = (void*)ucontext->uc_mcontext.gregs[REG_EIP];
  40.         bp = (void**)ucontext->uc_mcontext.gregs[REG_EBP];
  41. # endif

  42.         fprintf(stderr, "Stack trace:\n");
  43.         while(bp && ip) {
  44.                 if(!dladdr(ip, &dlinfo))
  45.                         break;

  46.                 const char *symname = dlinfo.dli_sname;

  47.                 fprintf(stderr, "% 2d: %p %s+%u (%s)\n",
  48.                                 ++f,
  49.                                 ip,
  50.                                 symname,
  51.                                 (unsigned)(ip - dlinfo.dli_saddr),
  52.                                 dlinfo.dli_fname);

  53.                 if(dlinfo.dli_sname && !strcmp(dlinfo.dli_sname, "main"))
  54.                         break;

  55.                 ip = bp[1];
  56.                 bp = (void**)bp[0];
  57.         }
  58. #else
  59.         fprintf(stderr, "Stack trace (non-dedicated):\n");
  60.         sz = backtrace(bt, 20);
  61.         strings = backtrace_symbols(bt, sz);

  62.         for(i = 0; i < sz; ++i)
  63.                 fprintf(stderr, "%s\n", strings[i]);
  64. #endif
  65.         fprintf(stderr, "End of stack trace\n");
  66.         return;
  67. }
  68. int setup_sigsegv() {
  69.         struct sigaction action;
  70.         memset(&action, 0, sizeof(action));
  71.         action.sa_sigaction = signal_segv;
  72.         action.sa_flags = SA_SIGINFO;
  73.         if(sigaction(SIGUSR1, &action, NULL) < 0) {
  74.                 perror("sigaction");
  75.                 return 0;
  76.         }

  77.         return 1;
  78. }



  79. void func1()
  80. {
  81.         raise(SIGUSR1);
  82.         return ;

  83. }
  84. void func2()
  85. {
  86.         raise(SIGUSR1);
  87.         return ;

  88. }

  89. void entry()
  90. {
  91.         func1();
  92.         func2();
  93.         return;
  94. }
  95. int main()
  96. {
  97.         setup_sigsegv();
  98.         entry();
  99. }
复制代码

gcc -o funstack -rdynamic -ldl funstack.c
初步看来还不错有空加到我原来俄内存检测程序中看看效果
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP