天天看點

iOS framework/靜态庫 nm 調試

iOS開發引入靜态庫時, 經常遇到類似錯誤

Undefined symbols for architecture x86_64: "_xxxx", referenced from: ...

。此時,可以進入到靜态庫所在目錄下,使用

nm

指令檢視該架構下是否存在該符号:

nm mySDK -arch x86_64 | grep '_xxxx'

功能

nm指令可以列出一個函數庫檔案(.o .a .so)中的符号表。所謂符号,通常指定義出的函數,全局變量等等。它對于靜态的函數庫和共享的函數庫都起作用。nm指令顯示的資訊用于調試庫和可執行檔案,對于一個給定的函數庫,nm指令可以列出函數庫中定義的所有符号,包括每個符号的值和類型。還可以給出在原程式中這個函數(符号)是在多少行定義的,不過這必須要求編譯該函數庫的時候加“-l”選項。

使用

nm [選項] [檔案清單(庫檔案/目标檔案/可執行檔案)]

有用的options:

-A

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

-B

全局非初始化資料段(BBS段)的符号,其值表示該符号在bss段中的偏移;

-b

全局static的符号;

-C

輸出demangle過了的符号名稱;

-D

列印動态符号,隻顯示動态符号,當使用動态庫時很有用;

-g

隻顯示全局符号的相關資訊;

-l

使用對象檔案中的調試資訊,為每一個符号查找和顯示所在源檔案及行号;

-N

debug用的符号;

-n

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

-r

const型隻讀的變量(readonly);

-T

位于代碼區的符号,比如函數main;

-t

位于代碼區的符号,一般是static函數;

-u

列印出那些未定義的符号,即位于目标子產品的外部符号,比如系統的printf()函數;

-w

給出更多警告資訊;

-V

nm指令版本号;
常見的符号類型:

A

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

B

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

D

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

T

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

U

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

W

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

舉例

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

nm -u hello.o

顯示hello.o 中的未定義符号,需要和其他對象檔案進行連結。

nm -A /usr/lib/* 2>/dev/null | grep "T memset"

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

nm AlipaySDK -arch arm64 | grep '_RSA_ver'

AlipaySDK

這個framework中,查找

arm64

架構下的

_RSA_ver

符号。