.PDB文件,全稱爲「程序數據庫」文件。咱們使用它(更確切的說是看到它被應用)大多數場景是調試應用程序。目前咱們對.PDB文件的廣泛認知是它存儲了被編譯文件的調試信息,做爲符號文件存在。那麼,它具體包含哪些內容呢?在調試過程當中是怎樣發揮做用的呢?咱們有沒有辦法去操做這個文件呢?html
一個非託管C++程序的PDB文件包含以下信息:數據庫
說明:從XP SP2起就再也不啓用FPO。對於 .NET PDB文件,只包含上面說到的兩種信息:
- l 源文件名稱和行號
- l 局部變量名稱
.NET PDB文件包含如此少的信息,緣由在於其餘信息咱們能夠從元數據中獲取,因此也就沒有必要重複存儲了。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace dumptest { class Program { static void Main(string[] args) { } } }
E:\test\c#\dumptest\dumptest\obj\x86\Debug>dumpbin /headers dumptest.exe Microsoft (R) COFF/PE Dumper Version 10.00.30319.01 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file dumptest.exe PE signature found File Type: EXECUTABLE IMAGE FILE HEADER VALUES 14C machine (x86) 3 number of sections 4E92A178 time date stamp Mon Oct 10 15:40:40 2011 0 file pointer to symbol table 0 number of symbols E0 size of optional header 102 characteristics Executable 32 bit word machine OPTIONAL HEADER VALUES 10B magic # (PE32) 8.00 linker version 800 size of code 800 size of initialized data 0 size of uninitialized data 272E entry point (0040272E) 2000 base of code 4000 base of data 400000 image base (00400000 to 00407FFF) 2000 section alignment 200 file alignment 4.00 operating system version 0.00 image version 4.00 subsystem version 0 Win32 version 8000 size of image 200 size of headers 0 checksum 3 subsystem (Windows CUI) 8540 DLL characteristics Dynamic base NX compatible No structured exception handler Terminal Server Aware 100000 size of stack reserve 1000 size of stack commit 100000 size of heap reserve 1000 size of heap commit 0 loader flags 10 number of directories 0 [0] RVA [size] of Export Directory 26D4 [57] RVA [size] of Import Directory 4000 [588] RVA [size] of Resource Directory 0 [0] RVA [size] of Exception Directory 0 [0] RVA [size] of Certificates Directory 6000 [C] RVA [size] of Base Relocation Directory 2668 [1C] RVA [size] of Debug Directory 0 [0] RVA [size] of Architecture Directory 0 [0] RVA [size] of Global Pointer Directory 0 [0] RVA [size] of Thread Storage Directory 0 [0] RVA [size] of Load Configuration Directory 0 [0] RVA [size] of Bound Import Directory 2000 [8] RVA [size] of Import Address Table Directory 0 [0] RVA [size] of Delay Import Directory 2008 [48] RVA [size] of COM Descriptor Directory 0 [0] RVA [size] of Reserved Directory SECTION HEADER #1 .text name 734 virtual size 2000 virtual address (00402000 to 00402733) 800 size of raw data 200 file pointer to raw data (00000200 to 000009FF) 0 file pointer to relocation table 0 file pointer to line numbers 0 number of relocations 0 number of line numbers 60000020 flags Code Execute Read <strong>Debug Directories Time Type Size RVA Pointer -------- ------ -------- -------- -------- 4E92A178 cv 50 00002684 884 Format: RSDS, {99F34C5E-5BC3-4043-AE11-D85F7990AF00}, 1, E:\test\c#\dumptest\dumptest\obj\x86\Debug\dumptest.pdb </strong> SECTION HEADER #2 .rsrc name 588 virtual size 4000 virtual address (00404000 to 00404587) 600 size of raw data A00 file pointer to raw data (00000A00 to 00000FFF) 0 file pointer to relocation table 0 file pointer to line numbers 0 number of relocations 0 number of line numbers 40000040 flags Initialized Data Read Only SECTION HEADER #3 .reloc name C virtual size 6000 virtual address (00406000 to 0040600B) 200 size of raw data 1000 file pointer to raw data (00001000 to 000011FF) 0 file pointer to relocation table 0 file pointer to line numbers 0 number of relocations 0 number of line numbers 42000040 flags Initialized Data Discardable Read Only Summary 2000 .reloc 2000 .rsrc 2000 .text如今咱們將目光集中在代碼清單2中斜體加粗的部分,這裏咱們能夠找到調試路徑的信息,一個GUID值(99F34C5E-5BC3-4043-AE11-D85F7990AF00)和一個路徑(E:\test\c#\dumptest\dumptest\obj\x86\Debug\dumptest.pdb)。如今咱們已經清楚了調試器如何判斷PDB文件是否匹配,下面咱們再來看調試器是如何尋找PDB文件的。
Private Build與Public Build的區別c#
private build, 用來表示在開發人員本身機器上生成的build;public build,表示在公用的build機器上生成的build。對於public build,須要symbol server存儲全部的PDB,而後當用戶報告錯誤的時候,debugger才能夠自動地找到binay相應的PDB文件, visual studio 和 windbg都知道如何訪問symbol server。在將PDB和binay存儲到symbol server前,還須要對PDB運行進行source indexing, source indexing的做用是將PDB和source關聯起來。緩存
第一種方案是咱們在GAC的目錄中找到被安裝的程序集,而後將PDB文件拷貝到該目錄下。一般咱們安裝到GAC中的程序集會存在於相似這樣的路徑中:C:Windows\assembly\GAC_MSIL\Example\1.0.0.0__682bc775ff82796a,該示例目錄中「Example」表明程序集的名稱,「1.0.0.0」表明版本號,「682bc775ff82796a」表明程序集的Public Token。當你找到確切的目錄,將PDB文件放到該目錄下,調試器就能夠加載符號文件了。<configuration> <runtime> <developmentMode developerInstallation="true"/> </runtime> </configuration>在你打開了development模式後,若是DEVPATH沒有定義或路徑不存在的話會致使程序啓動時異常"Invalid value for registry"。並且若是在machine.config中開啓DEVPATH的使用會影響其餘的全部的程序,因此要慎重使用machine.config。
說明:服務器
subst用於路徑替換 ,將路徑與驅動器號關聯,就是把一個目錄看成一個磁盤驅動器來看,不過不能格式化。運用必定技巧,subst命令還能夠實現隱藏驅動器、特殊軟件的安裝、模擬光盤自動運行等功能。函數
用法格式工具
1、subst [盤符] [路徑] 將指定的路徑替代盤符,該路徑將做爲驅動器使用ui
2、subst /d 解除替代編碼
3、不加任何參數鍵入 SUBST,能夠顯示當前虛擬驅動器的清單。spa
[例子]
C:\DOS>subst a: c:\temp 將c:\temp虛擬化成a盤
C:\>subst a: /d? 解除替代
想到解決上面問題的方法了嗎?咱們只需將本機源碼的路徑虛擬化成一個磁盤,例如M,以後不管你將代碼部署到任何機器上,只需將被部署的路徑虛擬成M就能夠了,就不會出現符號文件和目標代碼不匹配的狀況了。