在本文中,我将向您介绍PVS-Studio,它是C和C ++代码的分析器,并向您展示如何在Visual C ++环境中使用它。 本指南专门针对初学者。
安装分析仪
PVS-Studio支持Microsoft Visual Studio 2019、2017、2015、2013、2012和2010。有关系统要求,请参阅
文档 。 当前,PVS-Studio可以分析用C,C ++,C#和Java编写的项目。 但是,本文重点关注在Visual C ++中工作并且正在寻求帮助以开始使用分析器的程序员。
可以在
此处下载安装包。 运行它之后,将为您提供许多集成选项(图1)供您选择。 无法使用的选项显示为灰色。
图1.集成组件选择窗口。安装PVS-Studio之后,打开Visual Studio的“关于”窗口,并确保已安装产品中存在分析仪。
检查项目
安装完成后,您可以继续检查项目。 您也可以尝试分析整个解决方案。 为此,请单击扩展→PVS-Studio→检查→解决方案(图2)。
图2.使用PVS-Studio检查解决方案。如果您在运行检查时遇到任何困难,请参阅我们网站上的“
PVS-Studio:故障排除 ”部分。 这些不是“确保插头已插入插座”之类的愚蠢提示。 本节介绍了用户报告的典型问题以及解决方法。
处理警告清单
检查完成后,诊断消息将出现在特殊窗口中。 该窗口包含许多元素,所有元素都用于操作列表,因此您只能查看感兴趣的警告。 但是,乍一看,它看起来有些复杂。
图3.警告窗口。 点击图片放大。窗口元素的完整概述可以在
文档中找到,但现在我们仅关注基本元素:
- 警告的确定性级别。 上面的屏幕截图显示了启用的中级和高级级别。 较低的级别更多地处理“代码气味”和警告,不幸的是,警告往往会产生过多的误报。 为什么有这么多的低级和中级警告而又那么少的高级警告? 答案是已启用MISRA诊断,其中包含诸如“该功能应只有一个出口点”之类的规则。 当然,您通常不需要这些诊断程序,因此默认情况下将其禁用。 注意:“ 如何快速检查PVS-Studio分析仪针对C和C ++代码给出的有趣警告? ”。
- 过滤器。 您可以按代码,CWE,文本,项目或文件过滤消息。
- 触发行号。 一些诊断程序可以引用许多行:这些警告在行号旁边带有省略号。
SAST
PVS-Studio是用于静态应用程序安全测试(SAST)的工具,这意味着它可以检测源代码中的潜在漏洞,并根据特定的分类显示相应的漏洞标识符。
PVS-Studio支持以下弱点分类:
- CWE
- SEI证书
- 米斯拉
要启用CWE代码,请打开分析器窗口的下拉菜单,然后勾选Show Columns> CWE
图4.从下拉菜单中启用CWE代码。另一种方法是在Visual Studio菜单栏的“扩展”>“ PVS-Studio”>“输出窗口”中显示CWE代码
图5. Extensions菜单中的PVS-Studio子菜单。与此不同的是,在选项窗口中启用了MISRA诊断:
图6.可检测到的弱点列表。您可以
在此处了解有关这些分类的更多信息。
从命令行检查项目
PVS-Studio_Cmd.exe是一个实用程序,可从命令行检查C ++ .vcxproj项目和解决方案。 如果您想自动化分析过程,这将很有用。 该程序可以在安装目录中找到,默认情况下为“ C:\ Program Files(x86)\ PVS-Studio”。
该实用程序具有多个
参数 ,但是您只需要三个即可开始使用:
- --target:要检查的项目或解决方案的文件。
- --output:将分析报告存储到的plog文件。
- --progress:跟踪分析进度。
开始检查后,您将看到以下内容:
图7. PVS-Studio_Cmd.exe实用程序的输出检查完成后,将在开始参数指定的目录中创建一个包含分析报告的plog文件。 可以使用PlogConverter.exe实用程序将该报告转换为其他格式,如果要在IDE中打开该报告,只需在Windows资源管理器中双击plog文件。
还可以从扩展菜单中打开报告文件:扩展> PVS-Studio>打开/保存>打开分析报告...
图8.从插件菜单打开分析报告。有关实用程序及其参数的详细信息,请参见
文档 。
抑制误报
分析仪提供了多种抑制误报的方法。 以下各节将对它们进行详细描述:
- 微调 。
- 质量抑制 ,当您只想抑制那些引用新代码或修改代码的警告时,此功能特别有用。
样本警告
让我们看一下分析仪发出的警告示例。 以下代码片段来自ReactOS项目:
VOID NTAPI AtapiDmaInit(....) { .... ULONG treg = 0x54 + (dev < 3) ? (dev << 1) : 7; .... }
PVS-Studio的诊断消息:V502也许“?:”操作符的工作方式与预期的不同。 '?:'运算符的优先级低于'+'运算符。 uniata id_dma.cpp 1610
0x54 +(dev <3)表达式将始终为
true :非null常量
0x54首先被添加到
(dev <3)表达式的结果中,该表达式的值可以为0或1,然后才是结果值与零比较。
正确的版本如下所示:
VOID NTAPI AtapiDmaInit(....) { .... ULONG treg = 0x54 + ((dev < 3) ? (dev << 1) : 7); .... }
我们已经通过在括号中包含
'?:'操作来解决该问题,因此其结果现在将取决于
(dev <3)表达式的结果。
结论
那是PVS-Studio for Visual C ++入门的简短介绍。 当然,它并未涵盖所有方面,因此欢迎访问我们的
博客 ,我们在其中详细说明了如何使用分析仪,并查看
文档以获取有关诊断消息和工具设置的完整说明。