PDB檔案:每個開發人員都必須知道的
PDB檔案:每個開發人員都必須知道的
http://www.wintellect.com/CS/blogs/jrobbins/archive/2009/05/11/pdb-files-what-every-developer-must-know.aspx
PDB檔案:每個開發人員都必須知道的
一 什麼是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:。
完!
感謝,Thanks!
作者:iTech
出處:http://itech.cnblogs.com/
本文版權歸作者iTech所有,轉載請包含作者簽名和出處,不得用於商業用途,非則追究法律責任!
相關文章
- 每個開發人員都應該知道的WebSockets知識Web
- 每個開發人員都應該知道的 10 個 GitHub 倉庫Github
- 每個開發人員都需要了解的一個SQL技巧SQL
- 每個開發人員應該知道的 10 個 Linux 命令Linux
- Reflect API:每個 JavaScript 開發人員都需要的瑞士軍刀APIJavaScript
- Vue開發必須知道的36個技巧Vue
- 每個JavaScript開發人員都應該瞭解UnicodeJavaScriptUnicode
- 10個Node.js 開發人員必須使用的IDENode.jsIDE
- 11個SEO人員必須知道的Chrome擴充套件外掛Chrome套件
- 每個JavaScript開發人員都應該知道的新ES2018功能(譯文)JavaScript
- 15 個必須知道的 Chrome 開發工具技巧Chrome
- 檔案管理,你必須要知道的三個要點
- 開發人員都應該知道的開源搜尋引擎
- 每個 Android 開發者必須知道的資源集錦Android
- 每個Java程式設計師都必須知道的四種負載均衡演算法Java程式設計師負載演算法
- Web開發人員應當知道的15個開源專案Web
- 新幹貨:開發人員都應該知道的CLI命令
- 每一個C#開發者必須知道的13件事情C#
- 每個Java開發人員應該知道的五種RESTful客戶端程式碼JavaREST客戶端
- 15個IT技術人員必須思考的問題
- 每個Android開發者必須知道的記憶體管理知識Android記憶體
- Android開發人員必備的10個開發工具Android
- 每個程式設計師都必須遵守的程式設計原則程式設計師
- 前端開發人員必須瞭解的七大技能圖譜前端
- Java開發人員必須重視HTML5的5點理由JavaHTML
- 開發ReactNative前必須知道的幾件事React
- 您必須知道的 Git 分支開發規範Git
- .NET開發人員必知的八個網站網站
- 每個運維人員應該知道的 10 個 Linux 命令!運維Linux
- 為什麼開發人員必須要了解資料庫鎖?資料庫
- 每個Java程式設計師必須知道的5個JVM命令列標誌Java程式設計師JVM命令列
- 每個 Android 開發者必須知道的訊息機制問題總結Android
- 3 條必須知道的軟體開發原則
- JavaScript 面試必須知道的 10 個概念JavaScript面試
- 15個必須知道的chrome開發者技巧Chrome
- 作為開發人員,這四類Code Review方法你都知道嗎?View
- 優秀的Java開發人員必備的6個技能!Java
- 90%的Java開發人員都會犯的5個錯誤Java