• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Khan's Notebook GCC/GNU/Linux Delphi/Window Java/Anywhere

            路漫漫,長修遠,我們不能沒有錢
            隨筆 - 173, 文章 - 0, 評論 - 257, 引用 - 0
            數據加載中……

            在C/C++程序里打印調用棧信息(轉載)

            原文出處  http://blog.csdn.net/yetyongjin/article/details/7759144

            以下不能windows + mingw下執行.  windows下參考 http://code.google.com/p/backtrace-mingw/
            我們知道,GDB的backtrace命令可以查看堆棧信息。但很多時候,GDB根本用不上。比如說,在線上環境中可能沒有GDB,即使有,也不太可能讓我們直接在上面調試。如果能讓程序自己輸出調用棧,那是最好不過了。本文介紹和調用椎棧相關的幾個函數。
             
            NAME
                   backtrace, backtrace_symbols, backtrace_symbols_fd - support for application self-debugging
            SYNOPSIS
                   #include <execinfo.h>
                   int backtrace(void **buffer, int size);
                   char **backtrace_symbols(void *const *buffer, int size);
                   void backtrace_symbols_fd(void *const *buffer, int size, int fd);
             
            以上內容源自這幾個函數的man手冊。
             
            先簡單介紹一下這幾個函數的功能:
            l backtrace:獲取當前的調用棧信息,結果存儲在buffer中,返回值為棧的深度,參數size限制棧的最大深度,即最大取size步的棧信息。
            l backtrace_symbols:把backtrace獲取的棧信息轉化為字符串,以字符指針數組的形式返回,參數size限定轉換的深度,一般用backtrace調用的返回值。
            l backtrace_symbols_fd:它的功能和backtrace_symbols差不多,只不過它不把轉換結果返回給調用方,而是寫入fd指定的文件描述符。
            Man手冊里,給出了一個簡單的實例,我們看一下:
             1 #include<execinfo.h>
             2 #include<stdio.h>
             3 #include<stdlib.h>
             4 #include<unistd.h>
             5 
             6 void myfunc3(void) {
             7    int j, nptrs;
             8    #define SIZE 100
             9    void *buffer[100];
            10    char **strings;
            11    nptrs = backtrace(buffer, SIZE);
            12    printf("backtrace() returned %d addresses\n", nptrs);
            13    /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
            14     *  would produce similar output to the following: */
            15  
            16    strings = backtrace_symbols(buffer, nptrs);
            17    if (strings == NULL) {
            18        perror("backtrace_symbols");
            19        exit(EXIT_FAILURE);
            20    }
            21  
            22    for (j = 0; j < nptrs; j++)
            23        printf("%s\n", strings[j]);
            24    free(strings);
            25 }
            26  
            27 static void  myfunc2(void) {   /* "static" means don't export the symbol */
            28    myfunc3();
            29 }
            30  
            31 void myfunc(int ncalls) {
            32    if (ncalls > 1)
            33        myfunc(ncalls - 1);
            34    else
            35        myfunc2();
            36 }
            37  
            38 int main(int argc,char *argv[]) {
            39    if (argc != 2) {
            40        fprintf(stderr,"%s num-calls\n", argv[0]);
            41        exit(EXIT_FAILURE);
            42    }
            43    myfunc(atoi(argv[1]));
            44    exit(EXIT_SUCCESS);
            45 }
            46  
            編譯:
            # cc prog.c -o prog
             
            運行:
            # ./prog 0
            backtrace() returned 6 addresses
            ./prog() [0x80485a3]
            ./prog() [0x8048630]
            ./prog() [0x8048653]
            ./prog() [0x80486a7]
             
            這樣,是輸出了調用棧,不過只是以十六進制輸出函數地址而已,可讀性很差。仔細看下man手冊,原來很簡單,編譯時加上個參數:
             
            重新編譯:
            # cc -rdynamic  prog.c -o prog
            通過gcc手冊,我們可以也解下參數的說明:
            -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.
             
            再執行:
            # ./prog 0
            backtrace() returned 6 addresses
            ./prog(myfunc3+0x1f) [0x8048763]
            ./prog() [0x80487f0]
            ./prog(myfunc+0x21) [0x8048813]
            ./prog(main+0x52) [0x8048867]
            /lib/libc.so.6(__libc_start_main+0xe6) [0xaf9cc6]
            ./prog() [0x80486b1]
             
            這回,可以看到函數名了。

            posted on 2012-12-17 22:12 Khan 閱讀(1635) 評論(0)  編輯 收藏 引用 所屬分類: GCC/G++跨平臺開發

            久久夜色tv网站| 蜜臀久久99精品久久久久久小说| 国产高清国内精品福利99久久| 久久久久免费精品国产| 女同久久| 久久福利青草精品资源站免费| 欧美午夜A∨大片久久 | 久久综合九色综合久99| 久久久久国产一区二区三区| 久久A级毛片免费观看| 亚洲国产日韩综合久久精品| 久久中文字幕一区二区| 久久精品人妻中文系列| 久久这里只有精品视频99| 91精品国产91久久久久福利| 久久精品日日躁夜夜躁欧美| 久久国产三级无码一区二区| 成人妇女免费播放久久久| 亚洲午夜久久久久妓女影院| 久久亚洲欧洲国产综合| 久久国产精品久久国产精品| 久久精品亚洲中文字幕无码麻豆| 久久这里有精品| 久久久久久久女国产乱让韩| 久久久高清免费视频| 理论片午午伦夜理片久久 | 日韩乱码人妻无码中文字幕久久| 亚洲精品乱码久久久久久不卡| 精品久久久久久国产牛牛app| 久久久国产精品网站| 久久国产精品77777| 久久久女人与动物群交毛片| 久久久久久亚洲精品成人| 久久AV高清无码| 99久久er这里只有精品18| 久久超碰97人人做人人爱| 国内精品久久久久伊人av| 久久伊人精品青青草原高清| 国产精久久一区二区三区| 久久精品成人免费观看97| 日日狠狠久久偷偷色综合免费|