使用以下简单文件:
using System;
public class Program{
[STAThread]
public static void Main(string[] args){
Console.WriteLine("Boo");
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用以下命令:
csc /target:exe /debug:pdbonly HelloWorld.cs
Run Code Online (Sandbox Code Playgroud)
如果运行此命令且PDB尚不存在,则PDB文件大小为12KB.否则,如果PDB文件存在,则新文件大小为14KB.
Microsoft (R) Visual C# Compiler version 4.0.30319.17929
.NET 4.5
Run Code Online (Sandbox Code Playgroud)
有什么想法可以解释这个吗?
更新:
Ant*_*ony 18
我的回答很简单,但也许不那么准确.让我们在PDB文件上使用一个调试工具:

唯一的区别是PdbAge现场.这意味着每次编译后都不会重新创建 PDB文件!此文件已被修改,这就是它的大小更改的原因.
我的猜测在本文中得到了证实.引用:
格式更改的最重要动机之一是允许程序调试版本的增量链接,这是Visual C++版本2.0中首次引入的更改.
另一个问题是这个文件究竟发生了什么变化?我在" Sven B. Schreiber"一书中找到了文件格式的最详细解释,"未记载的Windows 2000 Secrets:A Programmer's Cookbook" ".关键词是:
更新现有PDB文件时,PDB格式的更大好处变得明显.将数据插入具有顺序结构的文件通常意味着重新调整大部分内容.从文件系统借用的PDB文件的随机访问结构允许以最小的努力添加和删除数据,就像可以在文件系统介质上轻松修改文件一样.当流在页面边界上增长或缩小时,只有流目录必须重新洗牌.这一重要属性有助于PDB文件的增量更新.
他描述并非文件中的所有数据在每个时刻都有用.某些字节范围只是由零填充,直到在下一次编译期间修改该文件.
所以除了一些GUID和Age号之外,我无法分辨PDB文件中究竟发生了什么变化.读完那本书后你可以更深入了解.祝好运!
更新(15/03/2013):
我花了一些时间来比较文件.当我在HEX模式下打开它时,我看到标题中的差异:
文件的页面大小为512字节(+ 20h时为200h),页面数不同:120和124(相应地为078h和07Ch).在我的屏幕上,较小的文件位于左侧.好.文件大小的差异恰好是2048字节.这意味着编译器第二次添加4页数据.然后我找到了所有其他的差异.从开始的3/4文件包含小差异 - 像往常一样几个字节.但在2600h,我们看到:

看!该行/LinkInfo./names./src/files/c:\Windows\microsoft.net\framework\v4.0.30319\helloworld.cs被裁剪,现在包含不一致的信息.
我期待并在完整表示中的第二个(更大)文件中找到此行:
此信息现在被放置到自由空间(请参阅左侧的零).我猜,旧页面(带有损坏的字符串)被标记为未使用的空间.
在文件的最后,我发现了正好2048字节的新信息 - 都是零.从2E00h开始(十进制11776),结束于35F8h(十进制13816).我们记得,第一个文件的大小正好是11776个字节.
作为结论:我认为较大的文件不包含任何新信息.但我还是无法回答为什么编译器在ProgramDataBase文件的末尾添加了4个空页数据.我认为这些知识是编译器开发人员的秘密.
每次编译都会创建一个新的不同程序集。
如果您想深入了解到底有什么不同,那么您可能想看看这篇文章:“使用 clr 进行黑客攻击:比较程序集”。
编译之间的差异:
- 时间戳
- 无操作
- 模块定义 GUID
- 调试属性
- 第二个时间戳
- PDB-GUID
- 目录差异
- 多个 4 字节偏移量(DataDirectory.Debug、SizeOFData、AddressOfRawData、PointerToRawData、DataDirectory.MetaData)
我不确定第一次和第二次编译之间额外的 2kb 大小差异从何而来。但我猜想可能有一些信息在第一次构建期间未包含,但在每次后续编译时添加。