• <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 閱讀(1619) 評論(0)  編輯 收藏 引用 所屬分類: GCC/G++ 、跨平臺開發

            久久亚洲高清观看| 久久99国产综合精品| 亚洲精品99久久久久中文字幕| 亚洲国产精品无码久久青草| 久久久久久久波多野结衣高潮| 久久久久亚洲国产| 国产精品青草久久久久婷婷| 国产精品免费久久久久久久久| 久久青青草视频| 久久精品嫩草影院| 一本色道久久综合狠狠躁| 亚洲伊人久久大香线蕉苏妲己| 囯产精品久久久久久久久蜜桃| 国产精品va久久久久久久| 97久久婷婷五月综合色d啪蜜芽 | 国产午夜电影久久| 亚洲欧美日韩中文久久| 久久精品成人欧美大片| 狠狠色婷婷综合天天久久丁香 | 国产精品美女久久久久av爽| 亚洲中文字幕无码久久综合网 | 999久久久免费国产精品播放| 欧美牲交A欧牲交aⅴ久久| 久久毛片免费看一区二区三区| 久久夜色精品国产噜噜麻豆| 久久精品国产亚洲AV香蕉| 亚洲国产成人精品久久久国产成人一区二区三区综 | 午夜天堂av天堂久久久| 午夜精品久久久久成人| 久久成人国产精品一区二区| 99国产欧美精品久久久蜜芽| 久久久久久亚洲AV无码专区| 少妇精品久久久一区二区三区| 久久精品国产AV一区二区三区 | 久久精品免费全国观看国产| 三级韩国一区久久二区综合| 久久精品亚洲福利| 久久精品国产黑森林| 久久这里有精品视频| 日本欧美国产精品第一页久久| 亚州日韩精品专区久久久|