程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 一起talk C栗子吧(第一百二十五回:C語言實例--顯示文件名和行號)

一起talk C栗子吧(第一百二十五回:C語言實例--顯示文件名和行號)

編輯:關於C語言

一起talk C栗子吧(第一百二十五回:C語言實例--顯示文件名和行號)


各位看官們,大家好,上一回中咱們說的內置宏的例子,這一回咱們說的例子是:顯示文件名和行號。閒話休提,言歸正轉。讓我們一起talk C栗子吧!

我們在上一回中通過內置宏來顯示文件名和行號。這一回,我們介紹另外一個顯示文件名和行號的方法:使用addr2line這個工具來顯示文件名行號。

addr2line是一個調試工具,主要借助可執行文件中的調試信息,把某個地址轉換為程序中的文件名或者行號。該工具有多個選項,我們常用的選項是”e”和”f”。

例如:addr2line -e a.out 0x12345678 會顯示與0x12345678這個地址相對應的文件名和行號。 例如:addr2line -f -e a.out 0x12345678 會在原來的基礎上顯示與0x12345678這個地址相對應的函數名,當然了這兩個選項可以一起使用,這樣就可以同時顯示文件名,函數名和行號。

看官們,光說不練不是我們的風格,我們舉一個實際的例子,通過代碼來說明如何使用addr2line這個工具來顯示文件名和行號。

在例子中,我們首先運行func函數,然後在主函數中顯示函數func的地址。

int main()
{
    func();
    printf("address of func:%p \n",func);

    return 0;
}

函數func的定義如下,簡單起見,我們只在該函數中輸出一行語句,表示函數中運行。

void func()
{
    printf("func is running \n");
}

我們編譯該程序,並且加入調試信息,具體的命令如下:

gcc -g Ex082_addr2line.c -o s      //編譯生成名叫s的可執行文件

運行該文件,可以得到以下結果:

 ./s                       //運行該可執行文件
func is running    
address of func:0x804844d  //顯示了函數的地址

接著我們通過地址來查看文件名,行號和函數名,具體的命令如下:

addr2line -f -e s 0x804844d     //同時使用f和e選項,注意f需要基於e來運行,所以f在e前面
func                            //顯示與地址0x804844d對應的函數名
/home/talk8/Ex082_addr2line.c:8 //顯示與地址0x804844d對應的文件名和行號

看官們,正文中就不寫代碼了,完成的代碼放到了我的資源中,大家可以下載使用。從代碼中可
以看到func函數位於文件中的第8行。

最後我們來對比一下這兩種顯示文件名和行號方法的優缺點:

內置宏的優點:在程序運行時就能直接顯示出文件名和行號,不需要調試和其它第三方工具。 內置宏的缺點:需要在運行的程序中提前加入內置宏,否則不會顯示文件名和行號,此外,在程序中的哪 一行添加內置宏也是頭疼的事情,這個需要依據程序的需要來添加。 addr2line工具的優點:在調試程序的時候,通過某個地址直接顯示文件名和行號(地址通常在dump文 件獲取),最重要的是我們不需要在代碼中添加任何內容。 addr2line工具的缺點:需要在編譯時使用gcc的”g”選項來加入調試信息,這會增加編譯時間並且使目標文件的變大。此外,它需要使用程序中的地址才能顯示文件名和行號,如果沒有一個有效的地址,那麼 它就無能為力了,正所謂巧婦難為無米之炊嘛。

依據我的經驗來看,顯示文件名和行號主要是為快速找出程序中的錯誤。如果程序中的錯誤比較容易重現,那麼可以在程序中必要的地方提前加入內置宏,然後編譯,並且運行編譯後的程序。當重現錯誤時就會直接輸出文件名和行號。這樣就能快速定位到錯誤發生的文件和錯誤在文件中的位置。反之,如果程序中的錯誤不容易重現,那麼就可以使用addr2line這個工具了。當程序發生錯誤時,生成dump文件(杧核心轉儲文件),在該文件中找到錯誤發生時的地址,使用該工具就可以得到發生錯誤的文件和錯誤在文件中的具體位置。另外,如果沒有dump文件時,可以使用gdb進行調試,然後借助gdb的info命令查看相關函數的地址。

看官們,在實際工作中,我們寫的程序會發生各種各樣的錯誤。因此,希望大能夠自己動手熟練掌握這兩種顯示文件名和行號的方法 。並且結合我分享的經驗在不同的情況中使用不同的方法,快速地找出程序中的錯誤。

各位看官,關於顯示文件名和行號的例子咱們就說到這裡。欲知後面還有什麼例子,且聽下回分解 。


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved