Version: 6000.3
语言: 中文
适用于 Windows 的 Unity 调试指南
配置调试工具以在 Windows 中调试 Unity

在 Windows 中调试 Unity 简介

您可以使用各种工具和技术在 Windows 上调试 Unity 应用程序,并识别和解决运行时问题。

本指南介绍实用的调试类型,例如实时调试和取证调试。它还涵盖了符号和托管异常等重要概念,它们支持和增强调试过程。

统一符号

符号提供调试信息,包括函数名称、变量名称和源代码行号。此信息可帮助调试器(如 WinDbg 或 Visual Studio)将低级内存地址映射回可读、人性化的数据。

Unity 的符号存储 (http://symbolserver.unity3d.com/) 提供特定于 Unity 应用程序和开发的调试符号。可以将 Windows 调试器 (WinDbg) 或 Visual Studio(2019 及更高版本)配置为自动下载和解析这些符号,以帮助调试 Unity 应用程序。

有关如何设置 WinDbg 或 Visual Studio 以解析 Unity 符号的说明,请参阅配置调试工具以在 Windows 中调试 Unity

注意:根据设计,Unity 符号存储 URL 不是可浏览的网页。如果您直接在浏览器中访问该链接,它不会显示任何内容。这些符号只能通过调试工具访问。

内置调试工具

在Unity开发中,内置调试是指调试非托管代码的过程,非托管代码是用C、C++或汇编等低级语言编写的代码。这种类型的调试通常需要 Unity 的引擎代码,内置插件在 Unity 外部创建的一组代码,用于在 Unity 中创建功能。可以在 Unity 中使用两种插件:托管插件(使用 Visual Studio 等工具创建的托管 .NET 程序集)和本机插件(特定于平台的本机代码库)。更多信息
请参阅术语表
或外部库。

在 Windows 上,调试工具使用程序数据库 (PDB) 文件 (扩展名为 .pdb) 。这些文件存储相关二进制文件(如可执行文件 (.exe)或库 (.dll) 的符号信息,例如函数名称和行号。

使用此调试类型可分析低级别问题,例如内存损坏、访问冲突或与性能相关的问题。

若要有效地使用 Unity 的内置调试工具,必须将其配置为使用 Unity 符号,从而提供对特定于 Unity 的非托管代码的额外可见性。有关说明,请参阅配置调试工具以在 Windows 中调试 Unity

C# 托管调试

托管调试是指调试在托管运行时环境中运行的高级代码。在 Unity 中,这主要涉及调试 C# 的逻辑脚本一段代码,允许您创建自己的组件、触发游戏事件、随时间修改组件属性以及以您喜欢的任何方式响应用户输入。更多信息
请参阅术语表
编写以使用 MonoBehaviour 类和其他 Unity API 扩展游戏行为。

可以使用调试工具(如 Visual Studio)来调试 Unity 托管代码,但也可以使用 Unity控制台窗口Unity 编辑器窗口,显示 Unity 或您自己的脚本生成的错误、警告和其他消息。更多信息
请参阅术语表
.如果您在 Unity 编辑器中进入 Play 模式,则 Console 窗口会显示错误、警告和控制台消息。

实时调试

实时调试是将调试器附加到已运行的进程或捕获异常的进程的过程。若要使调试器发现问题,必须将调试工具设置为在生成中使用 Unity 符号。有关说明,请参阅设置 Visual Studio 以调试 Unity

有关如何在 Unity 中使用实时调试的说明,请参阅为 Unity 设置实时调试

注意:如果游戏可执行文件与游戏名称同名,则调试器可能难以找到正确的 .pdb 文件。如果调试器无权访问重命名的可执行文件,则尤其如此。

取证调试

当应用程序因崩溃而终止时,它们有时会生成故障转储文件。取证调试(或事后调试)是指分析此文件以调查崩溃的原因。

默认情况下,Windows 配置为将应用程序崩溃报告发送到 Microsoft 的 Dr. Watson 或 Windows 错误报告服务。但是,如果安装了 Visual Studio 或 WinDbg,Microsoft 会提供调试崩溃的选项。

Windows 提供了用于调查故障转储文件(.dmp 或 .mdmp)的工具。根据故障转储,您可能会找到堆栈信息或整个进程内存。故障转储文件包含有助于确定崩溃原因的信息。它通常包括堆栈跟踪,前提是堆栈完好无损且可用于分析。

若要调查转储文件,可以在 Visual Studio 或 WinDbg 中加载它。虽然 Visual Studio 更易于使用,但 WinDbg 提供了其他功能,这使其成为首选调试工具。

要了解如何让您的应用程序创建转储文件,请参阅为 Unity 设置取证调试

UnityMixedCallstack 插件

运行 Visual Studio 时,可以使用 Unity 的 Visual Studio Code 的 UnityMixedCallstack 扩展。此扩展将不可读的 Mono 托管堆栈帧转换为可读的堆栈帧,从而简化了内置代码调试。

Unity 中的托管异常

当托管代码中发生错误时,就会发生托管异常,例如,在 Mono 或 .NET 运行时下执行的 C# 代码。托管运行时的异常处理机制处理这些异常。

例如,当代码尝试访问 null 对象引用上的成员时,会发生 NullReferenceException。

示例:调试空引用异常

以下示例演示了附加了内置调试器的 null 引用的外观示例。

此示例演示触发 null 引用异常的 Unity C# 脚本:

    private string name = null;

    void Start()
    {
        Debug.Log(name.Length);
    }

当此代码使用内置调试器(如 Visual Studio)运行时,输出窗口将显示:

Exception thrown at 0x00000142725F6438 in Unity.exe: 0xC0000005: Access violation reading location 0x0000000000000010.

如果将 Visual Studio 与UnityMixedCallstack启用插件后,托管堆栈帧将变得可读,如以下调用堆栈所示:

    [Assembly-CSharp.dll] SpinMe:Start ()   Unknown
    [mscorlib.dll] (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr)    Unknown
    mono-2.0-bdwgc.dll!mono_jit_runtime_invoke(_MonoMethod * method, void * obj, void * * params, _MonoObject * * exc, _MonoError * error) Line 3445    C
    mono-2.0-bdwgc.dll!do_runtime_invoke(_MonoMethod * method, void * obj, void * * params, _MonoObject * * exc, _MonoError * error) Line 3068  C
    [Inline Frame] mono-2.0-bdwgc.dll!mono_runtime_try_invoke(_MonoMethod *) Line 3175  C
    mono-2.0-bdwgc.dll!mono_runtime_invoke(_MonoMethod * method, void * obj, void * * params, _MonoObject * * exc) Line 3115    

SpinMe:Start()由于混合调用堆栈插件而显示在调用堆栈中。如果没有插件,则方法名称不可读。

解决不可读的托管帧

托管帧是缺少详细信息(例如文件名或行号)的堆栈跟踪行。相反,它们显示Unknown.

要检索更详细的信息,您可以使用内置的mono_pmip功能。此函数接受堆栈帧的地址并返回包含信息的 char*。您可以调用mono_pmip在 Visual Studio 的“即时”窗口(调试> Windows > Immediate)进行调试。有关此函数的详细信息,请参阅在 Windows 上使用 Visual Studio 进行调试 (Mono)。

> `?(char*){,,mono-2.0-bdwgc.dll}mono_pmip((void*)0x1b45558c)`  
0x26a296c0 " Tiles:OnPostRender () + 0x1e4 (1B4553A8 1B4555DC) [065C6BD0 - Unity Child Domain]"`

注意:这仅适用于以下情况mono-2.0-bdwgc.dll符号加载完全。

其他资源

适用于 Windows 的 Unity 调试指南
配置调试工具以在 Windows 中调试 Unity