Visual C++ 中的地址消毒器






4.88/5 (6投票s)
尝试在 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