使用MSVC代码分析防止关键错误

微软技术分享 微软全球最有价值专家
全栈领域优质创作者
博客专家认证
2024-08-23 09:58:53

想象一下,你正深入到一个复杂的C++项目中,一切似乎都在顺利运行。但是,突然出现了一个关键的错误——一个需要更多远见的错误。我们都去过那里,对吧?这就是代码分析作为你的沉默守护者介入的地方。

代码分析是一个很好的工具,可以捕捉那些难以捉摸的错误,并确保您的代码符合最佳编程实践。它通过搜索已知会导致问题的特定代码模式来识别难以通过测试发现的缺陷。

分析结果显示在Visual Studio错误列表窗口中,并在编辑器中显示为波浪形。此功能检查有问题的代码模式,例如将元素计数转换为字节计数引起的缓冲区溢出和空指针解引用,即使代码看起来正确。在本博客中,我们将重点介绍MSVC代码分析,这是Visual Studio for C++中可用的不同类型的代码分析之一。

MSVC代码分析大放异彩

2014年,OpenSSL中Heartbleed漏洞的发现震惊了科技界。此关键漏洞是由缺少边界检查引起的,允许攻击者利用TLS心跳扩展并从服务器内存中读取敏感数据,包括私钥、用户名和密码。后果是巨大的,影响了数百万用户,并引起了广泛的恐慌。

现在,把自己想象成一个从事高风险项目的C++开发人员。你知道,即使是一个小错误也会导致严重的安全漏洞,就像Heartbleed一样。这就是MSVC代码分析成为您最佳盟友的地方。

MSVC代码分析是一种静态分析工具,用于检查您的代码在使用Microsoft Visual C++(MSVC)编译器时是否存在错误、潜在的改进以及是否符合编码最佳实践。例如,未能初始化项目中的指针(例如int*uninitializedPtr;)可能会导致不可预测的行为、崩溃和安全漏洞。考虑以下场景:您声明一个指针并将其初始化为nullptr(int*imageData=nullptr;)。稍后,您将尝试根据未初始化的宽度和高度变量(imageData=new int[width*height];)为指针分配内存。这可能会导致未定义的行为,因为宽度和高度在使用前没有初始化。如果在正确分配指针之前使用指针,可能会导致访问未初始化的内存,这是规则C6001所标识的,有助于您在这些问题成为关键问题之前发现它们。以下示例生成“使用未初始化的内存”警告:

#include <iostream> 

#include <stdexcept> 

 class ImageProcessor { 

public: 

    void processImage() { 

        int width, height; 

        int* imageData = nullptr; 

        try { 

            // Attempt to allocate memory based on width and height 

            imageData = new int[width * height]; // Uninitialized width and height 

            // Process the image data (this will cause undefined behavior) 

            for (int i = 0; i < width * height; ++i) { 

                imageData[i] = i; // Potentially accessing uninitialized memory 

            } 

            // Simulate further processing 

            std::cout << "Image processed successfully." << std::endl; 

        } 

        catch (const std::bad_alloc& e) { 

            std::cerr << "Memory allocation failed: " << e.what() << std::endl; 

        } 

        // Clean up allocated memory 

        delete[] imageData; 

    } 

}; 

现在,让我们使用这个例子来了解在Visual Studio中调用代码分析的不同方法。

背景代码分析

Visual Studio的这一不可或缺的功能是作为一个实时代码分析工具。此工具对您特别有益,因为它:

  • 对潜在问题提供即时反馈,帮助早期解决问题。
  • 专注于编辑器中当前打开的文件,简化活动开发过程中的分析。

打开或保存文件后,背景代码分析将自动运行。默认情况下,未初始化内存的警告将被启用,在编辑器中显示一个绿色的波浪线,并出现在错误列表中,如下例所示。

 此功能默认启用;但是,您可以通过导航到“工具”>“选项”>“文本编辑器”>“C/C++”>“高级”>“代码分析”>“禁用背景代码分析:False”来仔细检查该设置。

手动运行代码分析

除了后台代码分析,您还可以根据需要手动运行代码分析。您可以首先清除当前正在处理的文件中的所有警告,然后为当前项目调用代码分析。定期对整个解决方案运行代码分析,以保持整体代码质量。您还可以手动运行单个文件的代码分析。有几种方法可以手动运行代码分析。执行这些步骤中的任何一个都会在我们的示例的错误列表窗口中显示“使用未初始化的内存”警告。

菜单栏

打开项目。

  1. 从菜单栏中,选择“构建”->“在[解决方案|项目名称|文件]上运行代码分析”
  2. 从菜单栏中选择分析->运行代码分析->[在解决方案上|对“项目名称”运行代码分析|对文件运行代码分析]

键盘快捷键

  • 对于单个文件:Ctrl+Shift+Alt+F7

在运行代码分析中了解有关手动运行代码分析的不同方法的更多信息。

在生成时启用代码分析

此设置可确保每次构建项目或编译单个文件时都会自动运行代码分析。将代码分析视为检查项目的检查员。虽然这位检查员可能需要更多时间来检查一切,但及早发现潜在问题可以让人放心。您投入的额外时间对于确保代码的安全是必要的。要启用它,请执行以下操作:

  • 在Visual Studio中打开项目属性。
  • 导航到配置属性>代码分析>常规。
  • 在“生成时启用代码分析”中选择“是”选项。请注意,默认情况下禁用此选项,而默认情况下启用Microsoft代码分析。
  • 要查看所有默认选定的规则,包括用于检测未初始化内存的规则,请导航到“配置属性”>“代码分析”>“Microsoft”,然后单击“配置”。

在构建时启用代码分析后,构建示例代码将导致Visual Studio为以下行生成警告:imageData=new int[width*height];,表示宽度和高度未初始化。后台代码分析侧重于您正在积极处理的文件,而构建时分析可确保检查所有项目文件,捕捉当前文件中没有的任何遗漏问题。此警告将出现在“错误列表”窗口中。

Microsoft C++代码分析中的关键事件通过在错误列表中的选定警告中提供详细信息,帮助您快速识别和修复缺陷。它们跟踪代码流以查明根本原因,从而更容易理解变量初始化或分支等问题。例如,双击错误列表中的C6001“使用未初始化内存:宽度”警告将打开一个显示关键事件的新窗口。有关更多见解,请参阅Microsoft C++代码分析警告和关键事件博客。

代码分析规则和规则集 

Visual Studio for C++中的规则集是确保代码质量和符合标准的代码分析规则的集合。例如,启用MSVC规则C26440,“函数可以声明为'noexcept'”,建议在函数不抛出异常的情况下用'noexcect'标记函数。这可以提高性能和可靠性。

要创建添加了“函数可以声明为'noexcept'”规则的新自定义规则集,请执行以下步骤:

  1. 在Visual Studio中打开项目属性
  2. 导航到“配置属性”>“代码分析”>“Microsoft”。
  3. 在“活动规则”部分,单击“配置”
  4. 选中要包含在规则集中的规则的复选框。该操作将自动从“无”更改为“警告”。您可以根据需要更改此规则的严重性,可以使用“错误”、“信息”、“隐藏”、“无”或“继承”等选项。
  5. 使用新文件名保存规则集。自定义规则集现在已自动分配给项目。

要深入了解使用规则集的更多信息,请参阅使用规则集指定要运行的C++规则文章。

附加工具和技术 

Visual Studio提供了几个功能,可以提高代码质量并防止Heartbleed错误等问题。以下是一些你可能会觉得有用的工具:

Clang Tidy代码分析

Clang Tidy是与LLVM/Clang-cl编译器一起使用的工具,旨在使您的代码现代化,确保符合标准,执行静态分析,并自动格式化代码。使用MSVC工具集时,您可以配置Clang Tidy以补充或替换传统的代码分析过程。这有助于发现不同类型的问题,并提高整体代码质量。您可以在Visual Studio中使用Clang Tidy文章中找到更多详细信息。

抑制特定警告

在C++中抑制特定警告涉及将项目设置配置为忽略单行、代码段、文件或整个项目的某些编译器警告。这可以在项目级别完成,也可以使用Visual Studio的项目属性或“#pragma warning”指令对单个文件完成。通过抑制相关性较低的警告,您可以专注于最关键的问题,使构建输出更清晰易读,从而简化了识别和解决重大问题的过程。要深入了解此主题,请查看Suppress编译器警告文章。

值得注意的是,代码分析工具偶尔可能会产生误报。如果您遇到误报,请通过Visual Studio开发人员社区频道报告,并提供详细的重新报告代码和信息。这有助于我们提高代码分析工具的准确性,并确保更流畅的开发体验。

了解更多

要了解更多关于保护C++程序的信息,请访问“构建可靠和安全的C++程序”博客。有关MSVC后端的最新更新,请查看Visual Studio 2022版本17.10中的MSVC后端更新博客。

您的反馈对于帮助我们提升MSVC代码分析体验非常宝贵。请在下面的评论中或通过开发者社区分享您的建议。您也可以通过电子邮件联系我们visualcpp@microsoft.com或通过@VisualC上的X。

文章翻译于作者Mryam Girmay Program Manager, C++

...全文
153 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

2,820

社区成员

发帖
与我相关
我的任务
社区描述
微软技术社区为中国的开发者们提供一个技术干货传播平台,传递微软全球的技术和产品最新动态,分享各大技术方向的学习资源,同时也涵盖针对不同行业和场景的实践案例,希望可以全方位地帮助你获取更多知识和技能。
windowsmicrosoft 企业社区
社区管理员
  • 微软技术分享
  • 郑子铭
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

微软技术社区为中国的开发者们提供一个技术干货传播平台,传递微软全球的技术和产品最新动态,分享各大技术方向的学习资源,同时也涵盖针对不同行业和场景的实践案例,希望可以全方位地帮助你获取更多知识和技能。

予力众生,成就不凡!微软致力于用技术改变世界,助力企业实现数字化转型。

试试用AI创作助手写篇文章吧