• <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++跨平臺開發

            www.久久99| 久久久久一区二区三区| 久久久无码精品亚洲日韩软件| 国产99久久九九精品无码| 久久精品国产精品亚洲艾草网美妙| 内射无码专区久久亚洲| 久久无码人妻一区二区三区午夜| 88久久精品无码一区二区毛片| 一本久久综合亚洲鲁鲁五月天| 99久久精品日本一区二区免费| 久久精品免费大片国产大片| 亚洲国产精品18久久久久久| 久久99精品国产麻豆蜜芽| 色综合久久无码中文字幕| 亚洲精品无码专区久久同性男| 国产叼嘿久久精品久久| 青草国产精品久久久久久| 亚洲精品乱码久久久久久不卡| 狠狠色伊人久久精品综合网 | 久久亚洲欧美国产精品| 国产精品99久久久久久www| 亚洲va国产va天堂va久久| 日韩电影久久久被窝网| 成人精品一区二区久久| 久久99国产精品二区不卡| 久久久久99精品成人片直播| 国产精品久久久久免费a∨| 久久精品女人天堂AV麻| 国产亚洲成人久久| 久久久久97国产精华液好用吗| 久久精品一区二区三区不卡| 国产精品久久久久…| 国产精品久久久久无码av| 97久久久久人妻精品专区| 久久ZYZ资源站无码中文动漫| 久久中文骚妇内射| 久久久精品国产sm调教网站| 久久人人妻人人爽人人爽| 韩国免费A级毛片久久| 国产一区二区三区久久| 国产高潮国产高潮久久久91|