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

            久久久久国产成人精品亚洲午夜| 精品国产乱码久久久久久呢| 久久久国产精品亚洲一区| 精品无码久久久久久尤物| 久久久久亚洲av无码专区导航| 国产韩国精品一区二区三区久久 | 久久无码AV中文出轨人妻| 久久久久亚洲av无码专区| 色婷婷久久久SWAG精品| 粉嫩小泬无遮挡久久久久久| 亚洲精品美女久久久久99小说 | 精品综合久久久久久98| 高清免费久久午夜精品| 欧美va久久久噜噜噜久久| 久久精品中文字幕大胸| 久久久精品人妻无码专区不卡| 欧美久久精品一级c片片| 久久国产色AV免费观看| 国产精品九九九久久九九| 人妻少妇久久中文字幕 | 久久精品国产久精国产一老狼| 国产99久久久国产精免费| 亚洲国产成人久久综合碰碰动漫3d| 99久久免费国产精品特黄| 2021国内久久精品| 精品国产乱码久久久久久1区2区 | 日本福利片国产午夜久久| 狠狠色丁香久久综合婷婷| 国产L精品国产亚洲区久久| 国产综合免费精品久久久| 婷婷国产天堂久久综合五月| 久久精品成人影院| 久久久久久毛片免费播放| 久久精品亚洲精品国产欧美| 日韩欧美亚洲国产精品字幕久久久| 久久人人爽人人爽人人片AV高清 | 中文无码久久精品| 亚洲国产成人久久综合一区77| 麻豆精品久久久久久久99蜜桃| 久久久久国产精品熟女影院| 久久不见久久见免费影院www日本|