Skip to main content
与大多数 C++ 程序一样,游戏也可能出现一类影响程序正确性和稳定性的 bug,因此从 Visual Studio 2022 起,Microsoft C/C++ 编译器 (MSVC) 与 IDE 开始支持 AddressSanitizer (ASan) 技术。这是一种编译器与运行时技术,可零误报地暴露许多难以发现的 bug,例如:
  • alloc/dealloc 不匹配以及 new/delete 类型不匹配
  • 分配对堆过大
  • calloc 溢出与 alloca 溢出
  • 双重释放 (double free) 与释放后使用 (use after free)
  • 全局变量溢出
  • 堆缓冲区溢出
  • 对齐值的无效对齐
  • memcpy 与 strncat 参数重叠
  • 栈缓冲区上溢与下溢
  • return 后使用栈以及 scope 结束后使用
  • 内存中毒后使用
有关 ASan 的更多信息可在 Visual Studio 页面找到:AddressSanitizer(Microsoft Docs)。

在编译器中启用 ASan

Address Sanitizer 已集成到 Visual Studio 项目系统、CMake 构建系统和 IDE 中。项目可以通过额外的编译器选项 /fsanitize=address 或在 Visual Studio 中设置项目属性来启用 AddressSanitizer:
此选项与所有 x64 优化等级和配置兼容。然而,它与 edit-and-continueincremental linking/RTC 不兼容,在使用 ASan 编译之前必须禁用这些选项。
启用 ASan 时需要将一个额外的库链接到你的代码中。这个引用会由构建系统自动添加。这还要求你在项目的 Linker > General 下设置 “Additional Library Directories”。请确保 $(VC_LibraryPath_VC_x64) 值是列表中的最后一项,以防止它被用于其他库,如下所示:

ASan 运行时要求

当游戏在启用 ASan 的情况下构建时,需要在运行时提供一个额外的 DLL,该 DLL 启用相关功能。默认情况下,当在编译器中启用 ASan 时,它会将此 DLL 复制到项目的输出目录中,然后应与可执行文件一起部署到主机上。 如需要,可以在 Visual Studio 的 $(VC_ExecutablePath_x64) 目录中手动找到这些 DLL。根据构建版本,XBOX 需要以下两者之一:

运行时调试器支持

在附加调试器的情况下运行启用 ASan 的游戏时,如果发现错误,它会中断进入调试器并显示详细报告,让你能确定错误发生的位置。 但如果你在没有附加调试器的情况下运行(例如在自动化测试框架中),则错误信息会显示在标准输出上,游戏会终止。这可能有所帮助,但你可能需要更多状态信息来找到崩溃的根本原因,这就是 Crash Dump 支持发挥作用的地方。
如果你在没有附加调试器的情况下运行,且需要在此时解析符号,则需要将 llvm-symbolizer.exe 文件与游戏 EXE 一起部署。此文件与上文列出的 ASan 运行时 DLL 位于同一位置。

运行时 Crash Dump 支持

从 Visual Studio 16.9.8 或 16.10.2 起,可以配置 ASan 以保存包含与错误关联的元数据的崩溃转储文件。Visual Studio 中的调试器可以解析该转储文件中保存的元数据,为崩溃提供更多上下文。你可以按构建配置崩溃转储保存,存储这些二进制产物,然后在 IDE 中通过合适的源索引查看它们。 Crash Dump 文档可在此处找到: Configuring Crash Dumps(Microsoft Docs)。 但上述链接的方案需要设置环境变量,而 XBOX 上不支持此操作,因此实现了另一种方法。要为你的 XBOX title 添加 Crash Dump 支持,只需定义一个回调函数,向 ASan 提供所需的崩溃转储文件名信息即可,下面给出了三个示例。
为了遵循 Visual Studio IDE 约定,文件名通常以 .dmp 结尾。
对该函数返回的名称没有特定要求,但它必须是运行代码所在目标设备上的一个有效文件路径。例如,将崩溃转储写入主机上的 D: 盘,可以在开发期间轻松找到并取出它们。 我们还添加了修改所生成 crash dump 类型的能力。在有些场景下,简单的 “Triage” dump 足以查看进程失败位置的调用堆栈;但对于某些问题,你可能需要问题发生时的周围内存信息。为此,我们提供了三种 XBOX 平台支持的可配置 crash dump 类型,与主机及 xbWatson 生成的 crash dump 类型相匹配。
与前一个函数一样,此重写在 XBOX 上是可选的,但如果你希望在没有附加调试器的情况下使用 crash dump 来收集 ASan 信息,则强烈推荐使用。如果你提供了转储文件名但提供 dumptype 重写,则将无法在 XBOX 上生成有效的崩溃转储。
该回调返回一个数字,表示所需的 dump 类型。有效类型如下例所示:

示例 ASan 代码

以下代码演示了这些函数可以多么容易地添加到现有代码库中,并根据需要进行调整:
通过以下命令行编译该代码:
执行时,此代码将抛出一个 ASan 异常,并按上述函数所指定生成 crash dump。你可以将这些函数集成到现有代码库中,在启用 ASan 时按需生成 crash dump。

已知问题

  • Visual Studio 2019 (16.11) 的 ASan 与 Game OS 不兼容。
  • ASan DLL 与 Game OS 不兼容,17.12 和 17.13 的初始版本会加载失败。此问题已在 17.12.6 和 17.13.3 中修复。
  • Visual Studio 2022 中导致 Game OS 启动时崩溃的 ASan 支持回归问题,已在 17.14.29 中修复;Visual Studio 2026 中在 18.4.1 中修复。
  • 在 XBOX 上使用调试器运行时,会定期发出以下异常消息,可安全忽略:
最后修改于 2026年8月24日