当前位置: 首页 > 工具软件 > microsoft-pdb > 使用案例 >

Unity is only able to load mdb or portable-pdb symbols. [Filename] is using a legacy pdb format.

殷永嘉
2023-12-01

关于Unity 中的旧版 PDB 警告

Unity is only able to load mdb or portable-pdb symbols. [Filename] is using a legacy pdb format.

在处理我的项目时,我最近在Unity中遇到了一个我以前从未见过的警告:

Unity 只能加载 mdb 或 portable-pdb 符号。[文件名] 使用的是旧版 pdb 格式。
面对一条我不理解的消息,我做了任何开发人员都会做的事情:我搜索它。不幸的是,我发现了很多困惑,坦率地说,还有一些非常糟糕的建议。只有通过搜索各个部分,我才能辨别出发生了什么。幸运的是,事实证明,如果您了解基本概念,那么信息实际上非常清楚。因此,我正在写这篇博客文章,以帮助下一个直接搜索消息的人。
简短版
简而言之,此警告意味着 Unity 无法加载指定文件的调试符号。这不会阻止您的项目构建,但调试可能会更加困难,因为重要信息(即错误中的行号)可能丢失或不正确。您可以通过将 pdb 文件转换为 Mono (MDB) 使用的格式或配置有问题的项目以生成(新的)可移植 PDB 格式而不是旧格式来解决此问题。

什么是 PDB?
A PDB (aka.程序数据库)是描述相应二进制文件(.dll或.exe文件)的调试信息的文件。除其他事项外,它是编译代码(被修剪和优化)如何与其原始源代码关联的参考。如果没有PDB(或等效的东西),就不可能分辨出哪个指令对应于源代码中的哪一行(在大多数程序中,这不是一对一的关系。

PDB早于C#,最初是为编译成Windows本机指令(C / C++)的程序而设计的。然而,当微软首次开发C#时,他们决定扩展PDB以满足他们的需求,而不是创造新的东西。这也具有锁定调试文件的效果,因此它们只能在Windows中工作 - 这在当时并不是一个真正的问题,因为Microsoft的实现已经是Windows的。

当Mono被开发为跨平台的.NET替代方案(基于C#和CLI设计规范)时,他们发现PDB不是存储调试信息的合适解决方案。PDB规范是复杂的,专有的,并且记录很少,因此Mono开发人员被迫创建一个替代(MDB),以便在其各种支持的平台上进行编译和调试。由于Unity是跨平台的,并且建立在Mono之上,因此它也被设计为使用MDB文件**。

*尽管有一些限制和偶尔的差异
** 诚然,我个人不理解这方面有一些怪癖 - 例如:尽管是专有格式,但Unity在构建在Windows上运行的项目时可以(以某种方式)生成自己的PDB。
当微软创建自己的跨平台实现C#和CLI(.NET Standard)时,他们已经决定是时候摆脱旧的PDB格式,而是创建一个新的(名称令人困惑的)“可移植PDB”格式。这种新格式是从头开始编写的,旨在简化,开源和清晰地记录。随着时间的推移,Mono被更新为能够读取可移植PDB,最新版本的Unity也可以这样做。

为什么我会看到此警告?
据我所知,Unity从未支持使用旧版PDB文件进行调试,但是,直到最近,还没有明确的消息明确表示情况确实如此。相反,Unity会表现得好像它只有DLL - 执行良好,但偶尔会引起开发人员的困惑,因为调试信息不正确或不完整。重要的是,这并不影响Unity内部的项目 - 相反,这些问题通常只发生在使用单独编译的代码的开发人员身上:第三方库或使用Microsoft编译器(而不是Mono)编译的他们自己的库。

有趣的是,Unity本身并没有直接解决这个问题(缺少警告)——相反,是Visual Studio IDE集成提供了这个新的警告*。这种方法确实有一点意义:如果您使用的是Visual Studio IDE,那么您很可能已经使用相同的IDE编译了其他项目 - 因此PDB很可能是第一方库(就像我的情况一样)。不幸的是,这并不总是正确的 - 正如IDE集成代码明确跳过其他Unity软件包中的PDB**所证明的那样。

  • 不过,许多开发人员可能会在 Unity 更新的同时看到新的警告,因为最新版本的 Unity 会静默更新许多软件包(包括 VS IDE 集成)。
    ** 在撰写本文时,最新版本的软件包 (2.0.7) 也是如此
    解决问题
    有两种主要方法可以解决此问题:生成可移植的PDB,或将旧版PDB转换为MDB。对于这篇文章,我假设你想做前者 - 还有很多其他资源在线记录后一种方法*。生成可移植PDB非常简单:您只需要更改项目的“调试信息”属性。为此(使用 Visual Studio),请打开项目的生成设置(右键单击项目 ->属性 ->生成选项卡)。将“配置”下拉列表设置为所需的值**,然后打开“高级”设置。这将允许访问“调试信息”部分,允许您将其更改为“可移植”。就是这样 - 下一个版本将输出可移植PDB而不是专有的PDB格式。

  • 例如,通过使用 PDB 到 MDB 工具。
    **我个人使用“Release”:它预先配置为包含优化,并且在开发库时很容易使用“调试”,然后在稳定时构建“Release”配置。
    遗憾的是,如果您看到第三方库的此警告,则可能无法修复它。可以将 PDB 转换为 MDB,但如果第三方库来自包源(如 Open UPM),则无法更改包内容。在这种情况下,您最好的选择是与第三方联系(即通过报告问题)。或者,您可以完全忽略警告(只要您不调试第三方代码,它就不会影响您。

避免问题
避免此问题的一种简单方法是首先以跨平台框架(如 .NET 标准)为目标。通常,这在首次设置项目时最容易做到,但只需做一些工作,也可以迁移现有项目*。这样做还有一个优点,即可以避免在项目中意外包含仅限 Windows 的依赖项(如 WinForms)。在项目的初始设置期间执行此操作的工作流非常简单(只需从新建项目向导中选择一个 .NET 标准模板)。遗憾的是,此方法不适用于每个项目,因为 .NET Standard 仅提供 .NET Framework 中存在的 API 的子集。

*如果在现有项目中尝试此操作,请确保备份您的工作!更改目标框架可能会有风险,尤其是在 .NET Framework(仅限 Windows)和 .NET Standard/Core(跨平台)之间跳转时。
结论
如您所见,旧版 PDB 警告并不是什么大问题:它们不会导致重大问题,并且在许多情况下可以通过更改单个生成设置来修复。虽然这些警告只出现在那些将Visual Studio与Unity一起使用的人身上,但任何使用.NET Framework库的人都可以从进行这种更改中受益。我希望这篇文章能帮助你理解警告 - 包括如何修复它以及它存在的根本原因。

 类似资料: