VS2003/VS2005/VS2008编译器生成的PDB文件,PDB的签名看上去是一大串乱糟糟的字符串,其实这个字符串分为两部分,由一个随机生成的GUID 和一个称为Age的数字组成。例如:
C7B874892EAB42EBA4824FEABC928B612
前面32个字符是GUID的十六进制大写字符串描述,后面的数字“2”即Age,也是用十六进制字符描述,所不同的是这里用小写字母。
对于VS2005,经过反复测试,其PDB签名生成的规则如下:
(1)如果增量编译,并且编译前对应的pdb文件存在,则不修改GUID,每次Age数值增1。
(2)如果增量编译,但编译前pdb不存在,则重新生成新GUID,并重置Age为1。
(3)如果是全量编译,无论编译前是否存在pdb,都重新生成新GUID,并重置Age为2。
我做了一个有趣的测试,把一个完全不相干的,由另一个dll生成的pdb复制到目标pdb目录下,然后重命名为目标pdb文件名,然后启动增量编译,观察生成的pdb的签名,发现如规则(1)所描述,没有修改GUID,只是Age增1,这说明VS2005只是简单的判断了一下文件名是否相同就认为pdb存在,然后沿用之前pdb的GUID。
VS2005的这个机制存在一些隐患,当从一个编译目标Copy PDB文件到另外一个编译目录,很容易导致生成的pdb签名出现重合。以前远程调试QQ一个用户产生的bug时,曾遇到过加载到正确的dll,对应pdb装载也没有任何异常,但是call stack完全混乱了,显示的函数名全是错的,这说明加载了错误的PDB。当时为了利用PDB上传的命令行,曾经这样操作过,极有可能就是这个原因造成。
原文地址:http://blog.163.com/prevBlogPerma.do?host=libo.deng&srl=40157422201001142850754&mode=prev