Addr2line 工具(它是標準的 GNU Binutils 中的一部分)是一個可以將指令的地址和可執行映像轉換成文件名、函數名和源代碼行數的工具。這種功能對於將跟蹤地址轉換成更有意義的內容來說簡直是太棒了。
要了解這個過程是怎樣工作的,我們可以試驗一個簡單的交互式的例子。(我直接從 shell 中進行操作,因爲這是最簡單地展示這個過程的方法,如清單 4 所示。)這個示例 C 文件(test.c)是通過cat
一個簡單的應用程序實現的(也就是說,將標準輸出的文本重定向到一個文件中)。然後使用 gcc 來編譯這個文件,它會傳遞一些特殊的選項。首先,要(使用-Wl
選項)通知鏈接器生成一個映像文件,並(使用
-g
選項)通知編譯器生成調試符號。最終生成可執行文件 test。得到新的可執行應用程序之後,您就可以使用
grep
工具在映像文件中查找 main
來尋找它的地址了。使用這個地址和 Addr2line 工具,就可以判斷出函數名(main
)、源文件(/home/mtj/test/test.c)以及它在源文件中的行號(4)。
在調用 Addr2line 工具時,要使用 -e
選項來指定可執行映像是 test
。通過使用
-f
選項,可以告訴工具輸出函數名。
清單 4. addr2line 的一個交互式例子
$ cat >> test.c
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
$ gcc -Wl,-Map=test.map -g -o test test.c
$ grep main test.map
0x08048258 __libc_start_main@@GLIBC_2.0
0x08048258 main
$ addr2line 0x08048258 -e test -f
main
/home/mtj/test/test.c:4
$
查看U-BOOT的信息:
U-BOOT本身在編譯以後會有一個System.map文件,這裏我們就不用再次生成。就直接:
yoyoili@yoyoili-laptop:~/source/system_study/u-boot-1.3.4$ grep board_init System.map
33f92e8c T board_init
yoyoili@yoyoili-laptop:~/source/system_study/u-boot-1.3.4$ arm-softfloat-linux-gnu-addr2line 33f92e8c -e u-boot -f
board_init
/home/yoyoili/source/system_study/u-boot-1.3.4/board/fs2410/fs2410.c:69
就可以看到我們的board_init函數的地址和所在的文件。