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

            精品国产青草久久久久福利| 久久综合丁香激情久久| 香蕉99久久国产综合精品宅男自| 国产精品99久久久久久宅男| 久久婷婷五月综合97色直播| 久久婷婷人人澡人人| 久久久久久久久波多野高潮| 77777亚洲午夜久久多喷| 久久精品国产亚洲精品| 午夜精品久久久久久久久| 嫩草影院久久99| 亚洲AV无码1区2区久久| 久久99久久成人免费播放| 久久国产精品一国产精品金尊| 国产精品青草久久久久福利99| 亚洲中文字幕无码久久精品1 | 热re99久久精品国产99热| 亚洲欧美一级久久精品| 久久综合综合久久97色| 伊人久久精品无码av一区| 久久有码中文字幕| 精品久久久久久国产牛牛app | 狠狠狠色丁香婷婷综合久久五月| 精品久久久久久国产| 国产日韩欧美久久| 久久夜色精品国产亚洲| 精品久久久久香蕉网| 亚洲国产精品久久电影欧美| 一本久久综合亚洲鲁鲁五月天| 99久久精品无码一区二区毛片 | 亚洲人成无码网站久久99热国产| 99久久精品国产一区二区蜜芽| 久久精品国产亚洲AV嫖农村妇女| 午夜天堂av天堂久久久| 亚洲国产精品无码久久久蜜芽 | 亚洲午夜久久久影院伊人| 亚洲一级Av无码毛片久久精品| 欧美无乱码久久久免费午夜一区二区三区中文字幕 | 成人精品一区二区久久| 色综合久久精品中文字幕首页| 久久综合久久综合久久综合|