乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      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)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多