未在面向 .NET Framework 的 .NET 标准项目中加载的调试符号

Posted

技术标签:

【中文标题】未在面向 .NET Framework 的 .NET 标准项目中加载的调试符号【英文标题】:Debugging symbols not loading in .NET standard project targeting .NET Framework 【发布时间】:2018-12-24 03:37:54 【问题描述】:

我正在使用 Visual Studio 2017。我创建了一个 .NET Standard 库(让这个库为 Lib1)项目,其中包含两个 Target 框架 netstandard2.0 net46。然后我还有另外两个项目...一个是“纯”.NET Framework 4.6 控制台项目(我们称之为 Console46)和一个 .NET Core 控制台项目(我们称之为 ConsoleCore)。他们都引用了Lib1。

我在运行ConsoleCore项目的时候,可以调试下断点没有任何问题,但是运行Console46时,Visual Studio无法加载pdb文件,所以无法调试库,下断点等。

我尝试手动加载 PDB 文件,因为它是为 net46 创建的,但它也失败了。

我可以做些什么来解决这个问题?

谢谢!

【问题讨论】:

试用工具 -> 选项 -> 调试 -> 常规 -> 使用托管兼容模式 Microsoft 一直在修补 PDB 格式,使其更适合在 Unix 上运行的工具。当您使用的调试引擎还不理解这种新格式时,这可能是一个问题。 Steve 的评论就是一个很好的例子,它强制使用旧引擎,而它肯定对新格式一无所知。项目 > 属性 > 构建选项卡 > 高级按钮。将“调试信息”组合框从 Portable 更改为 Full。 我在@HansPassant 的建议下取得了成功 我在使用 teamcity 和 index 在 teamcity 符号服务器中创建符号时遇到同样的问题,生成的文件符号与调试时文件地址中的加载符号信息不兼容,例如 Sign+ffffffff\file.pdb @HansPassant 解决方案解决了!再次感谢 【参考方案1】:

在 cmets 中发布的@hans-passant 的答案是一个很好的解决方案。

我在 csproj 文件中使用此选项重建了我的 .NET-Core 库。以下是根据@hans-passant 的说明修改文件时添加到 csproj 的 sn-p(项目 > 属性 > 构建选项卡 > 高级按钮。将“调试信息”组合框从可移植更改为完整):

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DebugType>full</DebugType>
    <DebugSymbols>true</DebugSymbols>
  </PropertyGroup>

然后我将构建的 dllpdb 转储到我的 .NET-Framework 应用程序的 bin 目录中,然后我就可以进入我的 .NET-Core 代码了。

【讨论】:

【参考方案2】:

对于与您所描述的非常相似的事情,这是一个成功的解决方法。当我的“解决方案”仅包含 .NET Standard 项目并且我尝试使用外部 4.6.1 框架可执行文件(让我们从单独的解决方案中将其称为“Foo.exe”)进行调试时,我的断点也没有命中。

我的理解是有两个不同的调试器,.NET Core 调试器和完整框架调试器。我的 vs '解决方案' 默认为前者,因为这是其中唯一的项目类型。

最终对我有用的是欺骗 VS2019 使用完整框架调试器。

为此,我在解决方案中添加了一个占位符 4.6.1 Framework 控制台项目,并将其设置为启动项目。在 Debug 选项卡中,我将 Start Action 设置为完全相同,将 Start External Program 中的值指向与以前相同的值(“Foo.exe”)。现在断点工作了。

注意事项:

占位符应用不执行任何操作,并且从未真正运行过。 它不需要引用您尝试调试的其他 .NET Standard 程序集。 “Foo.exe”是在任何情况下都会附加的调试过程,但断点只会在 Startup Project 是 Framework 项目而不是 Startup Project 设置为 . NET Standard 项目在同一个解决方案中。

顺便说一句,如之前的帖子中所述,将“构建\高级\调试信息”设置为“完整”对我的方案没有任何影响,但谢谢你,这很有意义,值得一试!

【讨论】:

我又被愚弄了,这次很明显:Framework.exe 客户端总是从其执行目录加载 .dll(除非显式 Assembly.LoadFrom),但 DLL 通常不会无需重建复制引用的 DLL 的 Framework.exe 项目(除了重建 DLL 项目)就可以到达那里。因此,“仅”重建 DLL 项目会断开断点。 Framework.exe 将加载一个陈旧的副本,直到它被重建。如果 Framework.exe 位于单独的解决方案中,则很容易忽略这一点,因为当它们属于同一解决方案时它是自动的! 另一个好技巧:在您的框架解决方案中打开 DLL 解决方案中的 .cs 文件并运行。您可以在该 .cs 文件中设置工作断点,即使它不是解决方案的一部分。如果你问我,纯粹的魔法...... 更多好消息。最近,在 Visual Studio 2019 16.11.3 中分别针对 .NET Core 3.1 和 .NET Standard 2.0 构建 WinForms 项目似乎不再需要我原来的答案中列出的回旋。 (OP 是专门的 Framework 4.6)

以上是关于未在面向 .NET Framework 的 .NET 标准项目中加载的调试符号的主要内容,如果未能解决你的问题,请参考以下文章

在 Linux 上构建面向 .NET Framework 的 NuGet 包

在 Linux 上构建面向 .NET Framework 的 NuGet 包

内部 .NET Framework 数据提供程序错误 1025

为啥将我的目标框架从“.NET Framework 4 Client Profile”更改为“.NET Framework 4”会出现警告消息?

VS2013打开项目 提示Asp.net4.5未在web服务器上注册

渗透基础——命令行下安装Microsoft .NET Framework