Jam*_*ing 15 c# debugging source-server pdb-files
注意:我的目标关注点是使用常规MSIL定位CLR的C#,以防有些内容适用于此但不是更常见的情况.
最近发布了Sourcepack项目,该项目允许用户重写pdb文件中的源路径以指向不同的位置.当您拥有程序集的源代码时,这非常有用,但不希望尝试将其放入与构建时完全相同的文件系统位置.
http://lowleveldesign.wordpress.com/2011/08/26/sourcepack-released/
对于开源项目,使用http://www.symbolsource.org/作为简化项目用户获取符号和来源的方法是一个很好的主意.
但是,由于法律或方便的原因,使用这种方法的项目通常不太可行.此外,可能正在调试项目的人员组可能相对较小或包含在内.
默认情况下,项目的pdb包含指向磁盘上文件的指针(IIRC),然后源索引可以添加嵌入源位置指针的功能(例如,在版本控制系统中),然后使用源服务器指向实际获取源的指针.
看起来事情可能更简单(对于某些构建,例如调试和/或仅内部),只需将实际源放入pdb(实际上只是取消引用当前在PDB中写入的指针).看起来你可以跳过整个源服务器部分(至少在理论上)并消除对调试时故事的一些依赖.是否将源存储为压缩源在很大程度上是正交的,但是为了使现有调试器的实现更简单,第一遍可能不会这样做.
由于PDB匹配二进制故事已经非常好,因此将源放入PDB甚至比源服务器指针更好,因为指针可能会随着时间的推移而中断(源控制系统移动或更改为不同的系统,或者无论如何,但坐在PDB中的实际来源是"永远".
(这是在Tigran评论之后通过编辑添加的,询问有什么好处)
应该与之进行比较的"基线"场景是使用当今"普通"源服务器实例的"正常"调试体验.在那种情况下,(AFAIK)调试引擎从PDB获取指针(通过备用流),然后使用注册的源服务器尝试通过该指针获取源.由于给定的程序集通常包含多个源文件,因此有一个指针包含一个基本位置,或者PDB中有多个指针(或其他内容),但这应与此讨论正交.
对于保持源隐藏/不可访问的项目(大多数Microsoft产品,例如,包括Windows,Office,Visual Studio等),然后让PDB包含指针,FAR优于包括实际源(即使它是加密).没有必要的网络访问和权限,这样的指针毫无意义,所以这种方法意味着您可以将PDB发送给地球上的任何人,而不必担心他们能够访问您的来源(最糟糕的情况是,他们可以看到您的来源如何树的安排,我想).
但是,有两大组项目(特别是构建),其中"隐藏源"的好处不存在.
第一个是仅供有权访问源的人使用的构建.在你自己的机器上完成不会离开那台机器的构建就是一个很好的例子,因为攻击者无论如何都需要从你的文件系统中读取文件以获取源代码,因此从一个文件(.cs)读取另一个文件(. pdb)在攻击难度/向量方面是一个相对较小的差异.类似地,完成并推送到测试/暂存环境的构建,其中访问机器上的pdb的人员等于或者可以正常访问源的人员的子集.
第二个(有点明显)是开源项目,项目的来源无论如何都已经开放给所有人,因此隐藏任何人的来源没有任何好处.
请注意,这可以相对容易地扩展,以包括加密形式的源(因为我们已经在讨论必须存储格式/编码数据),但增加的复杂性将使这种情况可能不太有用而不仅仅是使用'普通'源服务器.
通过上面的描述,允许这一点的潜在好处列表包括(但不限于:)这些当下突然出现在我的脑海中:
注意:另一种方法是在实际程序集中包含源代码(例如,作为资源),但pdb是一个更好的选择(很容易发布没有pdb的构建,如果源代码在pdb中,则没有正常的运行时性命中因为程序集是相同的代码和相同的大小等)
从表面上看,这种支持看起来似乎不太难添加,但我觉得这是因为我对所涉及的机制并不是很了解,而不是实际上是一件简单的事情.实施.:)
我的猜测将是:
随着上面的喋喋不休,问题实际上是:
我读过这篇文章并想总结一下我的理解以便清楚起见
如今,调试器使用 PDB 来获取文件的磁盘路径以及编译后创建可执行文件的给定部分的校验和。然后,调试器尝试使用本地磁盘和可用符号服务器加载文件。根据此提议,我们只需将文件本身嵌入到 PDB 中即可跳过中间人。尤里卡,不再寻找来源!
作为一个以这种方式挖掘源代码的人,我喜欢用一个包来满足所有调试需求的想法。不过,这个提议有几个方面需要考虑。
第一个是将源代码实际嵌入到 PDB 中。这是非常可行的。PDB本质上是一个轻量级文件数据库。它编码的内容有结构,但据我所知,您可以将任何您想要的内容放入某些插槽中(例如局部变量值/类型)。某些插槽可能有大小限制,但我确信您可以发明一种编码方案来将大文件分成块。
第二个方面是让调试器实际从 PDB 加载文件,而不是在磁盘上搜索文件。我对调试器的那部分不太熟悉,但据我了解,它只使用两条信息来定位文件
我相当确定这是它传递到符号服务器的唯一信息。这使得实现符号服务器变得不可行,因为它无法访问 PDB(当然假设我是对的)。
我四处寻找,希望有一个可以重写的 VS COM 组件,它允许您拦截给定路径的文件加载,但我找不到。
我认为可行的一种方法是
但这并不完全是你想要的。