久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

c中如何打印函數(shù)調(diào)用堆棧?

 quasiceo 2013-02-19
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
還有一個相關(guān)的,, 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. }
復(fù)制代碼

gcc -o funstack -rdynamic -ldl funstack.c
初步看來還不錯有空加到我原來俄內(nèi)存檢測程序中看看效果

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多