65.9K
CodeProject 正在变化。 阅读更多。
Home

Visual C++ 中的地址消毒器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (6投票s)

2020年5月25日

CPOL

2分钟阅读

viewsIcon

20893

downloadIcon

130

尝试在 Visual C++ 中使用地址消毒器。

在这篇博文中,我将演示如何在 Visual C++ 中利用地址消毒器 (ASan) 来检查内存问题。MSVC 团队于 2019 年将 Clang ASan 移植到 Windows 平台,由于它仍处于实验阶段,请务必预计仍需修复一些问题。

在使用 Visual C++ 中的地址消毒器之前,必须通过 Visual Studio Installer 进行安装。选中 C++ 地址消毒器(实验性) 复选框,然后单击 修改 按钮。

安装 ASan 后,请务必将此路径添加到您的 PATH 环境变量中,以便您的可执行文件可以找到 clang_rt.asan_dynamic-i386.dll

<small>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\bin\Hostx64\x86</small>

通过单击 新建 按钮并粘贴路径到新行,然后单击 确定 来添加环境变量。

在您的 C++ 项目属性中启用 地址消毒器

截至撰写本文时,ASan 仅支持 Release 和 32 位构建。x64 支持正在开发中,即将推出。Debug 构建和 x64 支持在 Visual C++ Update 16.7 中得到支持。

控制台应用程序

将以下两行代码添加到 main 函数,以触发 ASan 检测内存访问违规,控制台应用程序将终止以显示导致此崩溃的源代码行号。由于控制台输出过于冗长,此处不显示。

int* arr = new int[10];
arr[10] = 1;

MFC 应用程序

尝试使用 ASan 构建 MFC 应用程序会导致这些多重定义符号链接器错误,因为 new 和 delete 运算符同时在 MFC 和 Clang 库中定义。我没有好的方法来解决此链接错误。我已提交一个 错误报告,请帮助投票,否则 Microsoft 将单方面关闭它而不解决问题。

2>uafxcw.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" 
(??2@YAPAXI@Z) already defined in clang_rt.asan_cxx-i386.lib(asan_new_delete.cc.obj)
2>uafxcw.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" 
(??3@YAXPAX@Z) already defined in clang_rt.asan_cxx-i386.lib(asan_new_delete.cc.obj)
2>uafxcw.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new[](unsigned int)" 
(??_U@YAPAXI@Z) already defined in clang_rt.asan_cxx-i386.lib(asan_new_delete.cc.obj)
2>uafxcw.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete[](void *)" 
(??_V@YAXPAX@Z) already defined in clang_rt.asan_cxx-i386.lib(asan_new_delete.cc.obj)
2>D:\TextPerfect\Source\Release\SDIScratchPad2.exe : fatal error LNK1169: 
one or more multiply defined symbols found

Win32 OpenGL 应用程序

最后,我尝试在 Win32 OpenGL 应用程序 上使用 ASan。为了确保 ASan 能够按预期工作,我添加了那两行有问题的代码。在确保 ASan 检测有效后,我删除了那两行代码。

int* arr = new int[10];
arr[10] = 1;

要在没有控制台的 GUI 应用程序中查看 ASan 输出,您必须使用 Visual Studio 调试您的 Release 构建应用程序。ASan 输出将显示在 Visual Studio 的输出窗格中。但是,您会注意到没有显示违规行号。为了解决这个问题,让我们为您的 Release 构建添加调试信息。

对于早期的控制台应用程序,此步骤是自动完成的。只要 OpenGL 应用程序能够顺利完成而不会崩溃,就意味着 ASan 没有在内存访问违规时被触发。

参考

历史

  • 2020 年 8 月 7 日:x64 ASAN 支持在 Visual Studio 2019 Update 16.7 中可用。已上传示例代码。
  • 2020 年 5 月 25 日:首次发布 x86 ASAN
© . All rights reserved.