PDB文件在第二次编译时变大,然后保持相同的大小

REA*_*REW 28 .net c# csc

使用以下简单文件:

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)

如果运行此命令且P​​DB尚不存在,则PDB文件大小为12KB.否则,如果PDB文件存在,则新文件大小为14KB.

Microsoft (R) Visual C# Compiler version 4.0.30319.17929
.NET 4.5
Run Code Online (Sandbox Code Playgroud)

有什么想法可以解释这个吗?

更新:

  1. 我没有使用.NET 3.5和.NET 4的评论.
  2. 使用pdb2xml(http://blogs.msdn.com/b/jmstall/archive/2005/08/25/sample-pdb2xml.aspx),我看不出小的和大的之间有什么区别.

Ant*_*ony 18

我的回答很简单,但也许不那么准确.让我们在PDB文件上使用一个调试工具:

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,我们看到: DIFF

看!该行/LinkInfo./names./src/files/c:\Windows\microsoft.net\framework\v4.0.30319\helloworld.cs被裁剪,现在包含不一致的信息.

我期待并在完整表示中的第二个(更大)文件中找到此行: DIFF2 此信息现在被放置到自由空间(请参阅左侧的零).我猜,旧页面(带有损坏的字符串)被标记为未使用的空间.

在文件的最后,我发现了正好2048字节的新信息 - 都是零.从2E00h开始(十进制11776),结束于35F8h(十进制13816).我们记得,第一个文件的大小正好是11776个字节.

作为结论:我认为较大的文件不包含任何信息.但我还是无法回答为什么编译器在ProgramDataBase文件的末尾添加了4个页数据.我认为这些知识是编译器开发人员的秘密.


Jen*_*s H 0

每次编译都会创建一个新的不同程序集

如果您想深入了解到底有什么不同,那么您可能想看看这篇文章:“使用 clr 进行黑客攻击:比较程序集”。

编译之间的差异:

  • 时间戳
  • 无操作
  • 模块定义 GUID
  • 调试属性
  • 第二个时间戳
  • PDB-GUID
  • 目录差异
  • 多个 4 字节偏移量(DataDirectory.Debug、SizeOFData、AddressOfRawData、PointerToRawData、DataDirectory.MetaData)

我不确定第一次和第二次编译之间额外的 2kb 大小差异从何而来。但我猜想可能有一些信息在第一次构建期间未包含,但在每次后续编译时添加。

  • 不过,你实际上只是重新表述了这个问题。“为什么 PDB 的大小在第一次和第二次编译之间会发生变化?” “因为编译器以某种方式改变了它的内容”。是的,但是这些变化是什么? (8认同)