PDB:Program Debug Database(程式調試資料庫)檔案
一 什麼是PDB檔案
大部分的開發人員應該都知道PDB檔案是用來協助軟體的調試的。但是他究竟是如何工作的呢,我們可能並不熟悉。本文描述了PDB檔案的儲存和內容。同時還描 述了debugger如何找到binay相應的PDB檔案,以及debugger如何找到與binay對應的原始碼檔案。本文適用於所有的Native和 Managed的開發人員。 在開始前,我們先定義2個術語:private build, 用來表示在開發人員自己機器上產生的build;public build,表示在公用的build機器上產生的build。private build相對來說比較簡單,因為PDB和binay在相同的地方,通常地我們遇到的問題都是關於public build。 所有的的開發人員需要知道的最重要的事情是”PDB檔案跟原始碼同樣的重要“, 沒有PDB檔案,你甚至不能debugging。對於public build,需要symbol server儲存所有的PDB,然後當使用者報告錯誤的時候,debugger才可以自動地找到binay相應的PDB檔案, visual studio 和 windbg都知道如何訪問symbol server。在將PDB和binay儲存到symbol server前,還需要對PDB運行進行source indexing, source indexing的作用是將PDB和source關聯起來。 接下來的部分假設有已經設定好了symbol server和source server indexing。TFS2010中可以很簡單地完成對一個新的build的source indexing 和 symbol server copying。
二 PDB檔案的內容
正式開始PDB的內容,PDB不是公開的檔案格式,但是Microsoft提供了API來協助從PDB中擷取資料。 Native C++ PDB包含了如下的資訊: * public,private 和static函數地址; * 全域變數的名字和地址; * 參數和局部變數的名字和在堆棧的位移量; * class,structure 和資料的類型定義; * Frame Pointer Omission 資料,用來在x86上的native堆棧的遍曆; * 原始碼檔案的名字和行數; .NET PDB只包含了2部分資訊: * 原始碼檔案名稱字和行數; * 和局部變數的名字; * 所有的其他的資料都已經包含在了.NET Metadata中了;
三 PDB如何工作
當你載入一個模組到進程的地址空間的時候,debugger用2中資訊來找到相應的PDB檔案。
第一個毫無疑問就是檔案的名字,如果載入 zzz.dll,debugger則尋找zzz.pdb檔案。
在檔案名稱字相同的情況下debugger還通過嵌入到PDB和binay的GUID來確保 PDB和binay的真正的匹配。
所以即使沒有任何的代碼修改,昨天的binay和今天的PDB是不能匹配的。可以使用dempbin.exe來查看binary的GUID。 在VisualStudio中的modules視窗的symbol file列可以查看PDB的load順序。
第一個搜尋的路徑是binary所在的路徑,如果不在binary所在的路徑,則尋找binary中hardcode記錄的build目錄,
例如obj\debug\*.pdb, 如果以上兩個路徑都沒有找到PDB,則根據symbol server的設定,
在本地的symbol server的cache中尋找,如果在本地的symbol server的cache中沒有對應的PDB,
則最後才到遠端symbol server中尋找。通過上面的尋找順序我們可以看出為什麼public build和private build的PDB尋找不會衝突。 對於private build有時我們需要在別人的機器上debug的情況,需要將相應的PDB與binary一起拷貝,
對於加入GAC的.NET的binary,需要將PDB檔案拷貝到C:\Windows\assembly\GAC_MSIL\Example\1.0.0.0__682bc775ff82796a類似的binary所在的目錄。
另一個變通的方法是定義環境變數DEVPATH,從而代替使用命令GACUTIL將binary放入GAC中。
在定義DEVPATH後,只需要將binary和PDB放到DEVPATH的路徑,在DEVPATH下的binary相當於在GAC下。
使用DEVPATH,首先需要建立目錄且對當前build使用者有寫入權限,然後建立環境變數DEVPATH且值為剛才建立的目錄,
然後在web.config,app.config或machine.config中開啟development模式,啟動對DEVPATH的使用 <configuration> <runtime> <developmentMode developerInstallation="true"/> </runtime> </configuration> 在你開啟了development模式後,如果DEVPATH沒有定義或路徑不存在的話會導致程式啟動時異常"Invalid value for registry"。
而且如果在machine.config中開啟DEVPATH的使用會影響其他的所有的程式,所以要謹慎使用machine.config。 最後開發人員需要知道的是原始碼資訊是如何儲存在PDB檔案中的。對於public builds,在運行source indexing tool後,
版本控制工具將代碼儲存到你設定的代碼cache中。對於private builds,只是儲存了PDB檔案的全路徑,
例如在c:\foo下的源檔案mycode.cpp,在pdb檔案中儲存的路徑為c:\foo\mycode.cpp。
對於private builds可以使用虛擬盤來增加PDB對絕對路徑的依賴,
例如可以使用subst.exe將原始碼路徑掛載為V:,在別人的機器上debug的時候也掛載V:。
pdb檔案包含了編譯後程式指向原始碼的位置資訊,用於調試的時候定位到原始碼,主要是用來方便調試的。在程式發布為release模式時,建議將 pdb檔案刪除, 同時,對外發布的時候,也把 pdb刪除,有利於保護程式
部落格參考來源:
http://www.cnblogs.com/itech/archive/2011/08/15/2136522.html