.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就能够了,就不会出现符号文件和目标代码不匹配的状况了。