gpt4 book ai didi

c# - 如何将源代码嵌入到pdb中,并让调试器使用它?

转载 作者:行者123 更新时间:2023-12-03 20:57:02 29 4
gpt4 key购买 nike

注意:我的目标是将C#与常规MSIL一起用于CLR,以防万一,某些情况下可以使用,但在较一般的情况下不行。

现有的一些源调试支持示例

最近发布了the Sourcepack project,它允许用户重写pdb文件中的源路径以指向不同的位置。当您具有程序集的源代码,但又不想尝试将其放入与构建时完全相同的文件系统位置时,这非常有用。

http://lowleveldesign.wordpress.com/2011/08/26/sourcepack-released/

对于开源项目,使用http://www.symbolsource.org/作为使项目用户轻松获取符号和源代码的一种方法是一个好主意。

问题

但是,在很多项目中,出于法律或方便的原因,使用这种方法不太可行。同样,可能正在调试项目的人员可能相对较小或受限制。

默认情况下,项目的pdb包含指向磁盘上文件(IIRC)的指针,然后源索引可以添加将指针嵌入源位置的功能(例如,在版本控制系统中),然后使用源服务器实际获取源的指针。

目标

仅将实际源代码放入pdb中(实际上只是取消引用当前写在PDB中的指针),看起来事情可能更简单(对于某些构建,例如debug和/或仅供内部使用)。这样看来,您可以跳过整个源服务器部分(至少在理论上是这样),并消除对调试时间的依赖。是否以压缩形式存储源在很大程度上是正交的,但是第一次尝试可能不会这样做,以使其更易于为现有调试器实现。

由于PDB匹配二进制的故事已经非常好,将源放入PDB甚至比源服务器指针还要好,因为指针可能会随着时间而中断(源控制系统移动或更改为其他系统,或者(无论如何),但PDB中的实际来源是“永远的”。

这与“源服务器”支持有何不同?

(这是在Tigran的评论询问会有什么好处之后通过编辑添加的)

可以与之进行比较的“基准”场景是当今使用“正常”源服务器实例的“正常”调试经验。在那种情况下,调试引擎(AFAIK)会从PDB获取指针(通过备用流),然后使用已注册的源服务器尝试通过该指针获取源。由于给定的程序集通常将包含多个源文件,因此要么有一个包含基本位置的单个指针,要么在PDB中(或其他东西)有多个指针,但这应与本讨论正交。

对于需要隐藏/不可访问源代码的项目(大多数Microsoft产品,例如Windows,Office,Visual Studio等),则使PDB包含指针比包含实际源代码要好得多(即使它是加密)。如果没有必要的网络访问权限和权限,此类指针就毫无意义,因此,这种方法意味着您可以将PDB交付给地球上的任何人,而不必担心它们能够访问您的源(最坏的情况是,它们会瞥见您的源如何我想树被安排了)。

但是,有2个大型项目(尤其是构建项目)不存在这种“隐藏源代码”的好处。

第一个是只能由仍然有权访问源代码的人使用的版本。在您自己的计算机上完成的构建永远不会离开该计算机是一个很好的例子,因为攻击者无论如何都需要从您的文件系统读取文件以获取源,因此从一个文件(.cs)到另一个文件(.cs)进行读取。 pdb)在攻击难度/向量方面的差异相对较小。同样,已完成的构建并将其推送到测试/分阶段环境,在此环境中,访问计算机上pdb的人员等于或可以“正常”访问源的人员的一部分。

第二个是(某种程度上很明显)开源项目,该项目的源代码已经对所有人开放,因此对任何人隐藏源代码都没有好处。

请注意,这可以相对容易地扩展为以加密形式包括源(因为我们已经在谈论必须存储格式/编码数据),但是这样做的额外复杂性将使这种情况可能不太有用。不仅仅是使用“正常”源服务器。

好处?

撇开上面的描述,允许这样做的潜在好处包括(但不限于:)此刻突然出现的这些好处:

  • 无需处理设置源服务器支持。 It Just Works(IJW),至少在/如果调试器知道要查看pdb的情况下才有效。
  • 同时,您仍然可以做一个“固定”源服务器,它只是一个提取源并将其反馈给调用者的虚拟对象。这样的配置对于每个人都可以是相同的(例如,使用localhost),仍然消除了当前实际配置源服务器
  • 的需要。
  • 无需构建即可包含“源索引”
  • 由于构建始终会读取源文件并写入pdb文件,因此,我们只是在修改pdb中写入的内容,而不会因为进行网络调用或读取内存中尚不存在的数据而受到任何构建时性能的影响。
  • 在“本地”构建支持放入源代码之前,这可能是一个简单的构建后步骤,可能首先通过Sourcepack项目的一个小分支实现,因为
    已经完成了读取/修改PDB文件的工作:)
  • 不依赖具有源代码控制系统
  • 的团队/项目
  • 不依赖于要检查到源代码管理系统中的每个文件的特定版本(大多数人不会为在IDE中执行的每个构建都进行检入)
  • 无需访问具有该文件的特定源代码管理系统

    DVCS情况下的
  • ,例如,PDB指针可能指向git或mercurial或其他任何“随机”实例,不一定是您可以访问
  • 的实例
  • 源服务器工具,用于将该版本追溯到您确实有权访问的源控制服务器实例(如果该版本甚至存在)还不存在AFAIK)
  • 如果项目死亡(被删除)或移动,则没有问题

    例如
  • ,如果项目从以下一项转移到另一项:自托管,sourceforge,github,bitbucket,codeplex,code.google.com等。
  • 如果您正在调试的计算机没有(或不足)网络访问权限,则没有问题
  • 例如,如果您正在将“网络KVM”放入用于调试问题的框中,但是它没有网络,或者它只能与断开连接的网络通信,从而无法访问源控制服务器。
  • 在极端情况下,能够从构建中恢复某些项目源。 ;)

  • 注意:另一种方法是将源代码包括在实际程序集中(例如,作为资源),但是pdb是一个更好的选择(易于交付没有pdb的版本,如果源代码位于pdb中,则不会产生正常的运行时性能影响因为程序集是相同的代码和相同的大小,等等)

    如何实现?

    从表面上看,添加这种支持似乎不太困难,但是我觉得这是因为我对所涉及的机制并不了解,而不是说这很简单。实现。 :)

    我的猜测可能是:
  • 添加一个构建后步骤,该步骤将执行类似于Sourcepack的操作,但不更改指针,而是将其替换为实际源。
  • 根据源服务器需要执行的操作,可能需要加上前缀,否则实际源将位于其他备用数据流中,并且“指针”被更新为“source-in-pdb:ads-foo”。 CS”或其他。前缀或指针可以包括源文件的存储方式(未压缩,gzip,bzip2等,以及文件编码)
  • 实现一个“源服务器”,该服务器实际上从有问题的pdb中提取源并将其返回。
  • 不知道源服务器“API”是否具有足够的信息来获取PDB的位置,更不用说它是否有权读取内容了。

  • 完整性检查?

    随着上面的胡言乱语,问题实际上是:
  • 这种事情已经存在了吗? (如果是,请提供指针!)
  • 假设尚不存在,上述内容是否适合作为首过实现?上面有没有陷阱或复杂性?
  • 假设上述内容为“否”和"is",是否有一个现有的项目对此有意义(接近或在其现有范围内)?
  • 最佳答案

    我已阅读此书,并希望总结一下我的理解以便清楚

    Today the debugger uses the PDB to gain the disk path to a file and checksum which was compiled to create a given section of an executable. The debugger then attempts to load the file using both the local disk and available symbol server. Under this proposal we would skip the middle man by just embedding the file itself into the PDB. Eureka, no more searching for source!



    作为以这种方式完成了相当一部分挖掘源代码工作的人,我喜欢为您的所有调试需求提供一个软件包的想法。但是,关于此提议有两个方面需要考虑。

    首先是将源代码实际嵌入到PDB中。这是非常可行的。 PDB本质上是一个轻量级的文件数据库。它的编码具有结构性,但AFAIK可以将所需的内容放入某些插槽(例如,局部变量值/类型)。某些插槽可能有大小限制,但是我敢肯定,您可以发明一种编码方案,将大文件分解为多个块。

    第二个方面是让调试器实际从PDB加载文件,而不是在磁盘上搜索文件。我不太熟悉调试器的那部分,但是据我了解,它仅使用2条信息来定位文件
  • 磁盘上的文件路径
  • 所述文件的校验和(用于消除同名文件的歧义)

  • 我相当确定这是传递给符号服务器的唯一信息。这使得实现符号服务器变得不可行,因为它无法访问PDB(假设我当然是对的)。

    我挖了希望有一个您可以重写的VS COM组件,它将允许您拦截给定路径的文件的加载,但我找不到。

    我认为可行的一种方法是
  • 将源代码嵌入到PDB中
  • 有一个工具可以将源提取到已知位置,然后重写PDB以指向该位置。

  • 虽然这不是您想要的。

    关于c# - 如何将源代码嵌入到pdb中,并让调试器使用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7311537/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com