.NET中pdb文件的作用
.NET中pdb文件的作用.PDB是Program Database的缩写,全称为“程序数据库”文件。我们使用它(更确切的说是看到它被应用)大多数场景是调试应用程序。目前我们对.PDB文件的普遍认知是它存储了被编译文件的调试信息,作为符号文件存在。
PDB文件什么时候产生?
PDB文件是在我们编译工程的时候产生的,它是和对应的模块(exe或dll)一起生成出来的。我们一般可能不会意识到PDB文件的重要性,因为如果只是我们本地进行开发,我们总是能够进行调适。这里我要引入两个概念:Private Build和Public Build。Private Build指的是在开发机器上的编译,Public Build指的是在负责编译的机器上的编译。
正如上面我所说Private Build一般不会有问题,因为在编译出来的机器上进行调试所有必要的文件都在该在的地方。所有大部分不能调试的问题都发生在Public Build的情况下。
如果你的应用程序需要发布或者当作产品卖得,你就需要特别注意要保存你发布出去的那个版本的PDB文件和源文件。注意:你只有一次机会保存着发布出去的PDB文件,如果你弄丢了将无法找回。<当然使用Reflector 类似的工具去调试也是可以的。
PDB与源文件
现在我们再来讨论一个开发人员经常问到的问题:源文件的信息是如何在PDB文件中存储的?对于Public Build,PDB文件存储的是如何利用版本控制工具从代码缓存获取源码代码的命令。对于Private Build,很显然,符号文件存储的是源代码的完整路径。
理想状态下,对于Public Build而言源代码索引和符号被缓存到符号服务器的操作都会自动执行,我们无需考虑源代码和符号文件在哪存储的问题。事实上,很多开发团队并没有公用的符号服务器或者源代码索引服务。对于一个小型项目而言,每个开发人员都有足够的磁盘空间来存储源代码和符号文件,也许不会过多的考虑这个问题。但是也许会有这样的场景:将一个Private Build项目转移到另一台机器上有30M的源码需要放到C盘,但是此时C盘只有20M的剩余空间该怎么办?我们能修改PDB文件中源码的路径吗?
我们前面提到没有办法修改PDB文件,但是这里有一个取巧的方法可以尝试,所谓山不向我走来,我向山走去。这里有一个工具恰好可以派上用场,它就是subst.exe,它是Windows自带的命令行工具,可以从cmd窗口启动。
cmd命令subst的说明:
subst用于路径替换 ,将路径与驱动器号关联,就是把一个目录当作一个磁盘驱动器来看,不过不能格式化。运用一定技巧,subst命令还可以实现隐藏驱动器、特殊软件的安装、模拟光盘自动运行等功能。
用法格式
一、subst [盘符] [路径] 将指定的路径替代盘符,该路径将作为驱动器使用
二、subst /d 解除替代
三、不加任何参数键入 SUBST,可以显示当前虚拟驱动器的清单。
[例子]
C:\DOS>subst a: c:\temp 将c:\temp虚拟化成a盘
C:\>subst a: /d? 解除替代
注:Private Build与Public Build的区别
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关联起来。
PDB文件会影响性能么?
可能有些人会觉得PDB文件的生成会对最终的应用程序的性能产生一定的影响,所以觉得在发布版中不应该生成PDB文件。
对于.NET应用程序来说,生成PDB文件不会影响编译器的优化,所以也完全不会影响应用的性能。只会对于生成的程序集中的一个DebuggableAttribute的属性产生影响。
Debug里有pdb,Release里也有pdb,他们有什么不同呢?
Debug里的PDB是full,保存着调试和项目状态信息、有断言、堆栈检查等代码。
Release 里的PDB是pdb-only,基本上:出什么错了+错误在哪行。