原文出處:http://www.vckbase.com/document/viewdoc/?id=1710
作者:Generad USam
一、何謂符號(hào)文件?
符號(hào)文件(Symbol Files)是一個(gè)數(shù)據(jù)信息文件,它包含了應(yīng)用程序二進(jìn)制文件(比如:EXE、DLL等)調(diào)試信息,專門用來作調(diào)試之用,最終生成的可執(zhí)行文件在運(yùn)行時(shí)并不需要這個(gè)符號(hào)文件,但你的程序中所有的變量信息都記錄在這個(gè)文件中。所以調(diào)試應(yīng)用程序時(shí),這個(gè)文件是非常重要的。用 Visual C++ 和 WinDbg 調(diào)試程序時(shí)都要用到這個(gè)文件。
在 Windows 系統(tǒng)中,符號(hào)文件以 .pdb 為擴(kuò)展名,比如:每個(gè) Windows 操作系統(tǒng)下有一個(gè) GDI32.dll 文件,編譯器在編譯該 DLL 的時(shí)候會(huì)產(chǎn)生一個(gè) GDI32.pdb 文件,一旦你擁有了這個(gè) PDB 文件,那么便可以用它來調(diào)試并跟蹤到 GDI32.dll 內(nèi)部。該文件和二進(jìn)制文件的編譯版本密切相關(guān),比如修改了 DLL 的輸出函數(shù),再編譯該 DLL,那么原先的 PDB 文件就過時(shí)了,不能再用老的 PDB 文件來做調(diào)試工作,而必須使用最新的 PDB 文件版本。
Visual C++ 編譯代碼后會(huì)在 Debug 或者 Release 目錄下生成一個(gè) PDB 文件。一般情況下,符號(hào)文件包括以下的數(shù)據(jù)信息:
- 全局變量(Global variables);
- 局部變量(Local variables);
- 函數(shù)名和它們的入口地址(Function names and the addresses of their entry points);
- FPO 數(shù)據(jù)(Frame Pointer Omission):Frame Pointer 是一種用來在調(diào)用堆棧(Call stack)中找到下一個(gè)將要被調(diào)用的函數(shù)的數(shù)據(jù)結(jié)構(gòu)源代碼的行序號(hào)(Source-line numbers);
二、如何得到和安裝符號(hào)文件?
- 先確定你的操作系統(tǒng)(OS)版本;
- 到微軟網(wǎng)站下載相應(yīng)的符號(hào)文件;
- 安裝符號(hào)文件,對(duì)于符號(hào)文件的安裝位置沒有特貝要求,可以安裝在任何目錄中;
- 設(shè)置環(huán)境變量,使得調(diào)試工具(比如:Visual C++、WinDbg、Ntsd、DrWatson 等)能找到符號(hào)文件;
安裝符號(hào)文件的注意事項(xiàng):
如果是手動(dòng)安裝符號(hào)文件,有一點(diǎn)很重要,那就是宿主機(jī)(Hostt Computer)上的符號(hào)文件必須與目標(biāo)機(jī)器(Target Computer)上的 Windows 版本相匹配。
這里所謂的宿主機(jī)指的是運(yùn)行調(diào)試會(huì)話的機(jī)器,在典型的雙系統(tǒng)調(diào)試會(huì)話環(huán)境中,宿主機(jī)可以是連接到目標(biāo)機(jī)器的任何機(jī)器。目標(biāo)機(jī)器指的是發(fā)生軟件組件、系統(tǒng)服務(wù)、應(yīng)用程序或操作系統(tǒng)運(yùn)行失敗的機(jī)器。也即是需要被調(diào)試的機(jī)器,它是調(diào)試會(huì)話關(guān)注的焦點(diǎn)。目標(biāo)機(jī)器可以近在咫尺,也可以位于完全不同的地方。有時(shí)我們也將目標(biāo)機(jī)器稱之為——被調(diào)試者(debuggee),那么與之對(duì)應(yīng),宿主機(jī)則可以稱為調(diào)試者(debugger)。
三、在 Visual C++ 使用符號(hào)文件的方法
在 Visual C++ 6.0 中的使用方法:
- 打開 Visual C++ 6.0 的 Workspace 文件(*.dsw);
- 進(jìn)入 Tools 菜單,選擇 Options 菜單項(xiàng) (Tools->Options);
- 單擊 Directoties 標(biāo)簽;
- 在 “Show directories for”下拉列表中選擇 “Executable files”;
- 將符號(hào)文件的路徑添加到 “Directories” 路徑列表中;
- 單擊 OK 完成;
在 Visual C++ .NET 2003 中的使用方法:
- 打開 Visual C++ .NET 的項(xiàng)目文件(*.vcproj);
- 在解決方案管理器中選中要使用符號(hào)文件的項(xiàng)目;
- 單擊右鍵進(jìn)入項(xiàng)目屬性對(duì)話框;
- 選擇“配置屬性”中的“調(diào)試”;
- 在與“調(diào)試”對(duì)應(yīng)的“操作”選項(xiàng)中有一個(gè)“符號(hào)路徑”,在此添加符號(hào)文件的路徑即可;
- 單擊 “確定” 完成;
四、如何產(chǎn)生 Release 版本二進(jìn)制文件對(duì)應(yīng)的 PDB 文件?
在 Visual C++ 6.0 中的方法:
- 打開 Visual C++ 6.0 的 Workspace 文件(*.dsw);
- 進(jìn)入 Project 菜單,選擇 Settings 菜單項(xiàng) (Project->Settings),打開項(xiàng)目設(shè)置對(duì)話框;
- 在 “Settings for”列表中選擇項(xiàng)目的 Release 配置;
- 單擊“C/C++”標(biāo)簽;
- 在“Category”下拉列表框中選擇“General”選項(xiàng);
- 在“Debug info”下拉列表框中選擇調(diào)試信息格式(具體選項(xiàng)參見圖一),在此不必禁用任何優(yōu)化選項(xiàng);
- 單擊“Link”標(biāo)簽;
- 在“Category”下拉列表框中選擇“Debug”選項(xiàng);
- 選中“Debug info”復(fù)選框,然后選擇需要的鏈接調(diào)試類型(具體選項(xiàng)參見圖一);
- 不要選擇“Separate types”復(fù)選框;
- 在“Project options”編輯框的最后添加如下指令:/opt:ref,icf;
- 重新生成(Rebuild)項(xiàng)目;
在 Visual C++ .NET 2003 中的方法:
- 打開 Visual C++ .NET 的項(xiàng)目文件(*.vcproj);
- 進(jìn)入 Project 菜單,選擇 Settings 菜單項(xiàng) (Project->Settings),打開項(xiàng)目設(shè)置對(duì)話框;
- 在 “配置”下拉列表中選擇項(xiàng)目的 “(活動(dòng))Release” 配置;
- 選擇“配置屬性”樹型節(jié)點(diǎn)中的“C/C++” ==〉“常規(guī)”;
- 設(shè)置右邊的“調(diào)試信息格式”選項(xiàng)(具體選項(xiàng)參見圖一);
- 選擇“配置屬性”樹型節(jié)點(diǎn)中的“鏈接器”==〉“調(diào)試”;
- 設(shè)置右邊的“生成程序數(shù)據(jù)庫文件”(具體選項(xiàng)參見圖一);
- 選擇“配置屬性”樹型節(jié)點(diǎn)中的“鏈接器”==〉“命令行”;
- 在“附加選項(xiàng)(D)”編輯框中添加如下指令:/opt:ref,icf;
- 按“確定”退出;
- 重新生成(Rebuild)項(xiàng)目;

圖一
五、關(guān)于 Free Build(也稱 Retail Build)和 Checked Build(也稱 Debug Build)
每個(gè)基于 NT 操作系統(tǒng)有兩種不同的程序生成模式,即:
- Free Build (或 Retail Build)
- Checked Build (或 Debug Build)
Free Build 生成的是最終用戶版本,針對(duì)生成的二進(jìn)制文件進(jìn)行了徹底的優(yōu)化,禁用了調(diào)試斷言,并剝離了調(diào)試信息。這樣一來使可執(zhí)行程序文件更小,加載更快,使用的內(nèi)存也更小。
Checked Build 生成的是測(cè)試和調(diào)試版本。它包含額外的 Free Build 所沒有的錯(cuò)誤檢查,參數(shù)驗(yàn)證和調(diào)試信息,Checked Build 有助于隔離和跟蹤可能導(dǎo)致不可預(yù)見的行為的問題,比如內(nèi)存溢出,不正確的設(shè)備配置。雖然 Checked Build 提供了額外的保護(hù),但與 Free Build 比較,它需要更多的內(nèi)存開銷和磁盤空間。由于可執(zhí)行程序包含符號(hào)調(diào)試信息;調(diào)試時(shí)要執(zhí)行附加的代碼、參數(shù)檢查和輸出調(diào)試診斷信息,從而導(dǎo)致性能下降。
六、系統(tǒng)符號(hào)文件的更新方法
系統(tǒng)符號(hào)文件指 Windows 操作系統(tǒng)依賴的那幾個(gè)重要的 DLL/SYS 和可執(zhí)行文件對(duì)應(yīng)的符號(hào)文件,常見的比如:gdi32.dll、Kernel32.dll、Kerberos.dll、psapi.dll、user32.dll等,使用 WinDbg 調(diào)試時(shí),你就會(huì)發(fā)現(xiàn)系統(tǒng)符號(hào)文件(PDB)有多重要,這些文件都與本地的 OS 密切相關(guān),比如,Windows 2000 打了SP補(bǔ)丁的話,那么必須更新系統(tǒng)符號(hào)文件才能進(jìn)行相關(guān)調(diào)試,原來的符號(hào)文件與打補(bǔ)丁后的系統(tǒng)就會(huì)不匹配,怎么辦呢? 可以通過網(wǎng)絡(luò)來更新!象下面這樣在 WinDbg 的 Symbols Path 里面輸入路徑:
SRV*D:\Symbols\websymbols*http://msdl.microsoft.com/download/symbols
(斜體部分是你在本地保存符號(hào)文件的路徑)
如果你不是通過代理上網(wǎng),那么在你用 WinDbg 打開一個(gè)被調(diào)試程序后,輸入 symchk 回車,WinDbg 就會(huì)自動(dòng)的連到微軟的網(wǎng)站根據(jù)你的機(jī)器的情況更新的 PDB 文件,并將它保存在上面斜體部分指定的本地路徑里,這樣你就可以確保你的符號(hào)文件版本和你機(jī)器上的文件版本一致。
如果你是通過代理上網(wǎng)那么你需要配置 IE 的連接設(shè)置。具體方法恕不贅言。