天天看點

Linux的nm檢視動态和靜态庫中的符号

列出.o .a .so中的符号資訊,包括諸如符号的值,符号類型及符号名稱等。所謂符号,通常指定義出的函數,全局變量等等。

nm [option(s)] [file(s)]

有用的options:

-A 在每個符号資訊的前面列印所在對象檔案名稱;

-C 輸出demangle過了的符号名稱;

-D 列印動态符号;

-l 使用對象檔案中的調試資訊列印出所在源檔案及行号;

-n 按照位址/符号值來排序;

-u 列印出那些未定義的符号;

常見的符号類型:

A 該符号的值在今後的連結中将不再改變;

B 該符号放在BSS段中,通常是那些未初始化的全局變量;

D 該符号放在普通的資料段中,通常是那些已經初始化的全局變量;

T 該符号放在代碼段中,通常是那些全局非靜态函數;

U 該符号未定義過,需要自其他對象檔案中連結進來;

W 未明确指定的弱連結符号;同連結的其他對象檔案中有它的定義就用上,否則就用一個系統特别指定的預設值。

注意幾點:

-C 總是适用于c++編譯出來的對象檔案。還記得c++中有重載麼?為了區分重載函數,c++編譯器會将函數傳回值/參數等資訊附加到函數名稱中去形成一個mangle過的符号,那用這個選項列出符号的時候,做一個逆操作,輸出那些原始的、我們可了解的符号名稱。

更詳細的内容見man page。這裡舉例說明:

<dl><dd></dd></dl>

nm -u hello.o<dl><dd>顯示hello.o 中的未定義符号,需要和其他對象檔案進行連結.</dd></dl>

nm -A /usr/lib/* 2&gt;/dev/null | grep "T memset"

在 /usr/lib/ 目錄下找出哪個庫檔案定義了memset函數.