免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
c中如何打印函數(shù)調(diào)用堆棧?
c中如何打印函數(shù)調(diào)用堆棧?
 如何在一個函數(shù)中打印出來調(diào)用它的上一級函數(shù)名稱?
比如在做內(nèi)存泄漏檢測的時候,發(fā)現(xiàn)只打印分配內(nèi)存點的信息還不夠,因為有時候有多個流程同時調(diào)用一個地方分配內(nèi)存,最好能是象gdb那樣打印出函數(shù)調(diào)用的堆棧來更方便一些。
如果是c++還能想到用拋出異常來嘗試一下,c里面有什么好方法么?
原帖由 feasword 于 2007-6-17 20:06 發(fā)表
如題
如何在一個函數(shù)中打印出來調(diào)用它的上一級函數(shù)名稱?
比如在做內(nèi)存泄漏檢測的時候,發(fā)現(xiàn)只打印分配內(nèi)存點的信息還不夠,因為有時候有多個流程同時調(diào)用一個地方分配內(nèi)存,最好能是象gdb那樣打印出函數(shù)調(diào)用的 ...

何不直接參考 gdb 的源碼?

原帖由 feasword 于 2007-6-17 20:06 發(fā)表
如題
如何在一個函數(shù)中打印出來調(diào)用它的上一級函數(shù)名稱?
比如在做內(nèi)存泄漏檢測的時候,發(fā)現(xiàn)只打印分配內(nèi)存點的信息還不夠,因為有時候有多個流程同時調(diào)用一個地方分配內(nèi)存,最好能是象gdb那樣打印出函數(shù)調(diào)用的 ...
  1. func1(....)
  2. {
  3. .....
  4. #ifdef MYFEBUG
  5.      func2(....,__func__);
  6. #endif
  7. ....
  8. }
  9. #ifdef MYFEBUG
  10. func2(....,const char* funcname)
  11. #else
  12. func2(...)
  13. #endif
  14. {
  15. #ifdef MYFEBUG
  16.        printf("%s:%s\n",__func__,funcname);
  17. #endif
  18. ....
  19. }
可以參考strace,我好像還用過一個什么trace。。。。的

這問題C版ms討論了很多次了,info gcc  
__builtin_return_address
__builtin_frame_address
還有一個相關的, info libc
glibc中,
backtrace
backtrace_symbols
試驗了一下,好像只能打印出地址,但是有函數(shù)名更方便些
在11樓的提示下在網(wǎng)上找了篇文章,自己裁減了一下

  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
初步看來還不錯有空加到我原來俄內(nèi)存檢測程序中看看效果
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
善用backtrace解決大問題
巧用backtrace系列函數(shù),在不具備gdb環(huán)境的Linux系統(tǒng)上大致定位...
C 語言打印backtrace方法
usb初始化過程——基于pic18f2550
2013搜狗校園招聘筆試題
Android Native 內(nèi)存泄漏系統(tǒng)化解決方案
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服