GCC 生成的符號表除錯資訊剖析

2021-06-22 20:11:07 字數 3555 閱讀 1929

gcc把c語言原始檔('.c')編譯成組合語言檔案('.s'),彙編器把組合語言檔案翻譯成目標檔案('.o'),最後由鏈結器鏈結所有的目標檔案和有關的庫生成可執行檔案('a.out')。

如開啟'-g'選項,gcc編譯'.c'檔案時,把附加的除錯資訊插進'.s'檔案,這些除錯資訊經彙編器和鏈結器稍加轉換一直傳到可執行檔案中。這些除錯資訊包括行號、變數的型別和作用域、函式名字、函式引數和函式的作用域等原始檔的特性。

在 某些目標檔案中,除錯資訊用'.stab'打頭的一類彙編指導命令表示,這些指導命令穿插在彙編**中,這種除錯資訊格式叫'stab',即符號表 (symbol table)。xcoff和a.out目標檔案格式採用stab除錯資訊格式。此外,gcc也能在coff和ecoff目標檔案格式中產生stab。如要 生成stab除錯資訊,在gcc編譯原始檔時,開啟編譯選項'-gstabs+'(此選項將產生gnu偵錯程式擴充套件的stab的除錯資訊)或'- gstabs'。

彙編器處理'.stab'打頭指導命令,把stab中的除錯資訊填入'.o'檔案的符號表和串表(string table)中,鏈結器合併所有'.o'檔案生成只含有乙個符號表和乙個串表的可執行檔案。偵錯程式通過檢索可執行檔案中的符號表和串表來獲得程式的除錯信 息,下面分別介紹stab的格式,gcc生成stab和彙編鏈結器對stab轉換。

1 stab的格式

stab彙編指導命令有3種格 式:'.stabs'(string), '.stabn'(number)和'.stabd'(dot)。在mips機器上,gcc採用'.stabn'輸出源程式語句行號的stab除錯資訊, 而未使用'.stabd',因此,在mips機器上,gcc生成的帶有stab除錯資訊的彙編**中只含'.stabs'和'.stabn'兩種彙編指導 命令,'.stabs'和'.stabn'命令格式如下:

.stabs ″string″,type,other,desc,value

.stabn type,other,desc,value

下面說明stab彙編指導命令的各域。

″string″的一般格式是:″name:sym-desc type-info″

其中,name是由stab表示的符號的名字,如果stab表示是乙個匿名物件,則name可省略,一般以一空格代替。sym-desc為一字母,它具體表示stab所描述的是哪一類符號,例如:

sym- desc為'f',表示stab描述的是全域性函式;為'f'時,表示區域性函式;為'g'時,表示全域性變數。type-info則表示資料型別資訊,它可以 是stab分配給已定義的資料型別的序號,表示對已定義的資料型別的引用;也可以是一串符號,用來定義一種新的資料型別,參見1.3資料型別定義。

other沒有使用,其值保持零。

desc用編譯開關'-gstabs+'編譯原始檔,desc為源程式的語句行號;用編譯開關'-gstabs'編譯原始檔,desc為零。

value可為一符號位址,或為自動變數在當前棧裡相對幀指標的偏移量,或為暫存器變數所分配的暫存器的號碼。

以下各小節將結合例項對stab描述除錯資訊的格式作具體的闡述。

1.1 stab描述程式結構

(1)原始檔的名字和路徑

在含有除錯資訊的彙編**中,第乙個stab彙編指導命令指明所編譯的原始檔的名字,如果開啟gcc編譯開關'-gstabs+',還會指明該源文明所在的目錄,例如:

.stabs ″usr/people/ycq/work / ″, 100, 0, 0, $ltext( ) #100 is n-so

.stabs ″example.c″, 100, 0, 0, $ltext( )

其中type為n-so,表示該stab描述的是原始檔的名字或路徑,$ltext( )表示與該檔案相對應的**區的首位址。

(2)包含檔案

描述包含檔案的stab指明隨後出現的變數、函式等符號所要參考的原始檔,偵錯程式由此查詢到定義該符號的原始檔。string為被包含檔名,type=n-sol,value為被包含檔案**區的首位址,如:

.stabs ″example.c″, 132, 0, 0, $ltext1 #132 is n-sol

(3)行號

行號表示匯程式設計序中的一段**所對應的c源程式的語句行號。彙編指導命令採用'gstabn',type=n-sline,desc表示源程式的語句行號,value為該語句行所對應的一段彙編**的起始標號,例如:

.stabn 68, 0, 4, $lm6 #68 is n-sline

如果一源程式行所產生的彙編**不連續,可用多條'.stabn'表示,而desc為同一值。

(4) 函式 描述函式的stab,其type為n-fun,value為函式的符號位址。sym-desc=f表示該函式為全域性函式,sym-desc=f表示該函式 的為區域性函式,type-info表示該函式的返回值的資料型別。下列為stab描述區域性函式func,其函式返回值為整型。

.stabs ″func: fl ″, 36, 0, 0, func #36 is n-fun

(5)巢狀函式 巢狀函式是gnu c對標準c的擴充,stab描述巢狀函式與描述一般函式的方式大致相同,區別是在描述巢狀函式時,在type-info之後緊接包含該函式的最內層函式。

下面為一巢狀函式定義的例子,隨後給出了其stab描述。

int funx (int x)

{int funy (int y)

{int funz (int z){return x+y+z; }

return funz (x+y);

}return funy (x);

}生成的stab為:

.stabs ″funz: fl, funy″, 36, 0, 0, funz.5

.stabs ″funy: fl, funx″, 36, 0, 0, funy.2

.stabs ″funx: fl″, 36, 0, 0, funx

作用域的描述格式是:type-info之後跟','號,然後被描述的函式名跟','號,最後是包含該函式定義的最內層函式的名字。

(6) 塊結構 這裡塊結構是指c語言函式定義中表示塊語句開始和結束的左、右括號。描述左括號的('{')stab,其type=n-lbrac,value為以 '$lbb'打頭的彙編語句標號;描述右括號('}')的stab,其type=n-rbrac,value為以'$lbe'打頭的彙編語句標號。彙編指 導命令為'.stabn'。例如:

.stabn 192, 0, 0, $lbb2 #192 is n-lbrac

.stabn 224, 0, 0, $lbe2 #224 is n-rbrac

1.2 stab描述變數

在c語言裡,根據變數所具有的不同的儲存分配方式,可把變數分為:自動變數、全域性變數、暫存器變數和靜態變數。

(1)自動變數 自動變數儲存在當前函式棧裡,因此也叫

棧變數。stab描述自動變數時,type為n-lsym,stab描述自動變數在當前函式棧裡相對於幀指標的偏移量,sym-desc被省缺,如:

.stabs ″x: l″, 128, 0, 0, -12 #128 is n-lsym

(2)全域性變數 全域性變數的作用域不侷限於定義它的那個檔案,可為多個檔案使用。stab描述全域性變數時,type為n-gsym,sym-desc為g,value為零,偵錯程式根據全域性變數的外部符號獲得其位址,如:char gvar='c';

生成的含stab的彙編**為:

符號表的作用

在編譯程式中符號表用來存放語言程式 現的有關識別符號的屬性資訊,這些資訊集中反映了識別符號的語義特徵屬性。在詞法分析及語法在分析過程中不斷積累和更新表中的資訊,並在詞法分析到 生成的各階段,按各自的需要從表中獲取不同的屬性資訊。不論編譯策略是否分趟,符號表的作用和地位是完全一致的 編譯程式掃瞄說明部...

windbg虛擬機器除錯符號表設定

在d盤建立乙個mysyssymbols資料夾,用於存放自己的符號檔案.然後給這個資料夾建立乙個快捷方式,把它放到c documents and settings 你的使用者名稱 sendto資料夾下.這樣,以後編譯完驅動以後,直接在符號檔案上右擊 傳送到 mysyssymbols 就可以了,很方便 ...

C C Lib庫檔案nm除錯之符號表

本文主要介紹了一下在linux下開發c c 時候,不可避免的會開發或者生成.o a so這種中間庫狀態的檔案 可能是自己寫了乙個lib讓別人呼叫,或者提供.c cpp檔案嵌入別人的makefile工程 如何檢視這些庫檔案的一些基本資訊。有時候大家編譯程式時候 確切的說是鏈結器鏈結的時候 很多錯誤例如...