新聞中心

        EEPW首頁 > 嵌入式系統 > 牛人業話 > C語言的那些小秘密之函數的調用關系

        C語言的那些小秘密之函數的調用關系

        作者: 時間:2015-03-09 來源:網絡 收藏

          顯示的調用關系是調試器的必備功能,如果我們在程序的運行中出現了崩潰的情況,通過的調用關系可以快速定位問題的根源,懂得調用關系的實現原理也可以擴充自己的知識面,在沒有調試器的情況下,我們也可以自己來實現顯示函數的調用關系。在我們自己動手寫backtrace函數之前,先來看看glibc提供的backtrace函數的使用。代碼如下:

        本文引用地址:http://www.104case.com/article/270700.htm

          #include

          #include

          #include

          #define MAX_LEVEL 4

          static void call2()

          {

          int i = 0;

          void* buffer[MAX_LEVEL] = {0};

          int size=backtrace(buffer, MAX_LEVEL);

          for(i = 0; i < size; i++)

          {

          printf("called by %pn", buffer[i]);

          }

          return;

          }

          static void call1()

          {

          call2();

          return;

          }

          static void call()

          {

          call1();

          return;

          }

          int main(int argc, char* argv[])

          {

          call();

          return 0;

          }

          在此先講解下backtrace()函數的使用:

          int backtrace(void **buffer,int size)

          該函數用來獲取當前線程的調用堆棧,獲取的信息將會被存放在buffer中,它是一個指針列表。參數 size 用來指定buffer中可以保存多少個void* 元素。函數返回值是實際獲取的指針個數,最大不超過size大小,在buffer中的指針實際是從堆棧中獲取的返回地址,每一個堆棧框架有一個返回地址。

          接下來的任務就是編譯運行了。

          root@ubuntu:/home/shiyan# gcc -g -Wall sss.c -o p

          root@ubuntu:/home/shiyan# ./p

          輸出結果為:

          called by 0x8048440

          called by 0x804847d

          called by 0x804848a

          called by 0x8048497

          上面的運行結果就是調用者的地址,看起來還不是那么的直觀,我們使用addr2line工具來實現地址到源代碼位置的轉換。

          運行

          root@ubuntu:/home/shiyan# ./p |awk '{print "addr2line "$3" -e p"}'>t.sh;. t.sh;rm -f t.sh

          輸出結果為:

          /home/shiyan/sss.c:12

          /home/shiyan/sss.c:27

          /home/shiyan/sss.c:34

          /home/shiyan/sss.c:40

          接下來看看在棧中數據的結構。

          

        c語言相關文章:c語言教程



        上一頁 1 2 下一頁

        關鍵詞: C語言 函數

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 溆浦县| 济阳县| 石门县| 肃南| 平武县| 塔河县| 田阳县| 海盐县| 台前县| 白玉县| 洛川县| 库车县| 蛟河市| 石台县| 潼南县| 汉川市| 濮阳市| 如东县| 丰原市| 隆子县| 安阳县| 广汉市| 砀山县| 苏州市| 景洪市| 古丈县| 阿拉善右旗| 乌拉特后旗| 棋牌| 博白县| 津南区| 大足县| 尼勒克县| 封丘县| 白玉县| 澳门| 额尔古纳市| 峨山| 合肥市| 夏津县| 沾化县|