PVS-Studio静态通用分析规则
通用分析
PVS - Studio产品包含了一套通用静态分析规则,用于检测在C / C ++/ C+11应用程序中大范围内的各种缺陷。
通用的规则集帮助您发现逻辑错误,拼写错误,导致访问冲突的代码片段,STL库算法的不正确使用等。
当选择PVS – Studio的执行规则时,我们首先要从他们的相关性开始。我们自觉拒绝执行像MISRA这样的标准,因为那里的大多数建议描述没有什么帮助,开发人员使用现代工具,如Visual Studio和STL,MFC,Qt和Boost等的库。在PVS-Studio中,我们尝试实施更好的诊断,不仅考虑C / C ++语言的细节,还考虑更高层次的模式以及代码和库的相互作用。许多检查是独一无二的,目前还没有被我们所熟悉的分析仪实现过。
PVS - Studio中检测到的错误模式是千差万别的。因此,我们接下来只说明工具有可以检测的某些类型错误。如果您想了解分析仪检测到的其他类型的错误,请参考相关文档。下面给出的错误样本均取自真实的项目。
当“+1”写错地方时,发生的错误
if ((t=(char *)realloc(next->name, strlen(name+1))))
{
next->name=t;
strcpy(next->name, name);
}
分析仪在这里发现了程序员不小心犯下的错误。程序分配比实际需要少2个字节的内存。为了纠正错误,你应该把“+1”从括号中拿出来。这是正确的代码:"realloc(next->name, strlen(name) + 1)"。
矩阵清理不彻底
#define CONT_MAP_MAX 50
int _iContMap[CONT_MAP_MAX];
memset(_iContMap, -1, CONT_MAP_MAX);
这个错误是指缓冲区欠载/超载类的。当只是处理数组的部分,或者反过来,修改数组外的内存时,这样的错误就会发生。在此示例中,memset()函数只清除小部分的_iContMap阵列。这里的错误是缺少sizeof():
memset(_iContMap, -1, CONT_MAP_MAX * sizeof(_iContMap[0]));
缺少非关联指针
if (pSlash != NULL) {
pSlash++;
if (pSlash != '\0') {
...
分析仪通常可以帮助检测可疑的指针处理,例如,下面的示例。这里指针跟0比较。如果该指针不等于0,它就+1,再次和0比较。这是很奇怪的操作。他们当然包含一个错误,因为非关联指针操作丢失:“if(!* pSlash='\ 0'){”。
不正确的循环
int i, destlen = 0, l, k;
for (i=0; i<srclen; i++)
{
...
for (k=i; i<srclen; k++)
{
if (src[k]=='>')
break;
}
i = k;
}
分析仪在这段代码中发现了一个错字: “it”变量代替“K”,用在嵌套循环比较中。此代码是很容易造成内存访问到正在处理的数组以外。
写错变量名
class CSize : public SIZE
{
...
CSize(POINT pt) { cx = pt.x; cx = pt.y; }
这个错误在项目中被发现,程序员使用自己的类CSIZE。由于书写错误,结果一个相同的变量被分配不同的值。这引起分析仪的注意。第二次分配操作的正确代码是:“cy = pt.y;”。
Windows API使用不当
OPENFILENAME lofn;
...
lofn.lpstrFilter = L"Equalizer Preset (*.feq)\0*.feq";
在Windows API的结构中,字符串指针必须以两个零结尾。在此示例中,在OPENFILENAME结构的lpstrFilter成员是一个指针。此代码将在过滤文件中的对话领域中产生的垃圾。这是正确的代码:
lofn.lpstrFilter = L"Equalizer Preset (*.feq)\0*.feq\0";
我们手工在行末写“0”,因为编译器将会添加多一个0
标准算法处理不当
我们上面所讨论的所有示例是低级错误。现在让我们看看在PVS-Studio实施的检查,处理更高层次的概念,如代码块或算法。
void unregisterThread() {
Guard<TaskQueue> g(_taskQueue);
std::remove(_threads.begin(), _threads.end(), ThreadImpl::current());
}
std::remove函数不从存储器中删除的项目。它只是转移项目和返回到垃圾的迭代器的起点。假设我们有矢量<int>存储器,它包含项目1,2,3,1,2,3,1,2,3。假如我们执行代码"remove( v.begin(), v.end(), 2 )",容器将包含项目1,3,1,3,?,?,?,这里“?”是一些垃圾。此外,该函数将返回第一个垃圾项目的迭代器,所以如果我们要去除这些垃圾项目,我们必须编写以下代码:"v.erase(remove(v.begin(), v.end(), 2), v.end())".这是正确的代码:
auto trash = std::remove(_threads.begin(), _threads.end(),
ThreadImpl::current());
_threads.erase(trash, _threads.end());
使用复制-粘贴方法编写代码的错误
void KeyWordsStyleDialog::updateDlg()
{
...
Style & w1Style =
_pUserLang->_styleArray.getStyler(STYLE_WORD1_INDEX);
styleUpdate(w1Style, _pFgColour[0], _pBgColour[0],
IDC_KEYWORD1_FONT_COMBO, IDC_KEYWORD1_FONTSIZE_COMBO,
IDC_KEYWORD1_BOLD_CHECK, IDC_KEYWORD1_ITALIC_CHECK,
IDC_KEYWORD1_UNDERLINE_CHECK);
Style & w2Style =
_pUserLang->_styleArray.getStyler(STYLE_WORD2_INDEX);
styleUpdate(w2Style, _pFgColour[1], _pBgColour[1],
IDC_KEYWORD2_FONT_COMBO, IDC_KEYWORD2_FONTSIZE_COMBO,
IDC_KEYWORD2_BOLD_CHECK, IDC_KEYWORD2_ITALIC_CHECK,
IDC_KEYWORD2_UNDERLINE_CHECK);
Style & w3Style =
_pUserLang->_styleArray.getStyler(STYLE_WORD3_INDEX);
styleUpdate(w3Style, _pFgColour[2], _pBgColour[2],
IDC_KEYWORD3_FONT_COMBO, IDC_KEYWORD3_FONTSIZE_COMBO,
IDC_KEYWORD3_BOLD_CHECK, IDC_KEYWORD3_BOLD_CHECK,
IDC_KEYWORD3_UNDERLINE_CHECK);
Style & w4Style =
_pUserLang->_styleArray.getStyler(STYLE_WORD4_INDEX);
styleUpdate(w4Style, _pFgColour[3], _pBgColour[3],
IDC_KEYWORD4_FONT_COMBO, IDC_KEYWORD4_FONTSIZE_COMBO,
IDC_KEYWORD4_BOLD_CHECK, IDC_KEYWORD4_ITALIC_CHECK,
IDC_KEYWORD4_UNDERLINE_CHECK);
...
}
要发现这段代码中的错误是非常困难的。但PVS - Studio的耐心和学识:“V525:代码包含相似的块的集合。在行576,580,584,588”中检查项目'7','7','6','7'。让我们缩短的代码,使错误更明显:
styleUpdate(...
IDC_KEYWORD1_BOLD_CHECK, IDC_KEYWORD1_ITALIC_CHECK,
...);
styleUpdate(...
IDC_KEYWORD2_BOLD_CHECK, IDC_KEYWORD2_ITALIC_CHECK,
...);
styleUpdate(...
IDC_KEYWORD3_BOLD_CHECK, IDC_KEYWORD3_BOLD_CHECK,
...);
styleUpdate(...
IDC_KEYWORD4_BOLD_CHECK, IDC_KEYWORD4_ITALIC_CHECK,
...);
此代码最有可能是使用了复制粘贴的方法,导致使用IDC_KEYWORD3_BOLD_CHECK而不是IDC_KEYWORD3_ITALIC_CHECK。您在诊断消息中看到的数字出现这样的宏:
#define IDC_KEYWORD1_ITALIC_CHECK (IDC_KEYWORD1 + 7)
#define IDC_KEYWORD3_BOLD_CHECK (IDC_KEYWORD3 + 6)
最后一个样本具有特别重要的意义,因为它表明,PVS - Studio 分析器同时处理整个大的代码片段,检测重复的结构,并根据启发式方法,认为这代码具有潜在危险。
使用通用分析的好处
静态分析最宝贵的是,你可以在开发初期检测一些错误。一个错误越早检测到,消除它就越容易、快速、便宜。这减少了测试和维护阶段的费用。
静态分析仪处理源代码,检查程序执行中所有可能的方式。因此,您可能会发现在很少使用的代码中或在你打算使用该项目的下一阶段的代码中的错误。
PVS - Studio是一个现代分析仪,没有沉重的过往负担。它积极地发展和学习,检测现在程序员使用Microsoft Visual C + +遇到的错误的新模式。您可能在这一领域帮助我们,并为我们提供你自己发明的诊断规则。在反馈页面给我们发送您的建议。
PVS-Studio静态通用分析规则的更多相关文章
- 来试试这个来自静态代码分析工具PVS Studio提供C++的小测验吧
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:来试试这个来自静态代码分析工具PVS Studio提供C++的小测验吧.
- pmd静态代码分析
在正式进入测试之前,进行一定的静态代码分析及code review对代码质量及系统提高是有帮助的,以上为数据证明 Pmd 它是一个基于静态规则集的Java源码分析器,它可以识别出潜在的如下问题:– 可 ...
- 常用 Java 静态代码分析工具的分析与比较
常用 Java 静态代码分析工具的分析与比较 简介: 本文首先介绍了静态代码分析的基 本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代码分析工具 (Checkstyle,FindBu ...
- 11个Visual Studio代码性能分析工具
软件开发中的性能优化对程序员来说是一个非常重要的问题.一个小问题可能成为一个大的系统的瓶颈.但是对于程序员来说,通过自身去优化代码是十分困难的.幸运的是,有一些非常棒的工具可以帮助程序员进行代码分析和 ...
- C++静态代码分析PreFast
1历史 Prefast是微软研究院提出的静态代码分析工具.主要目的是通过分析代码的数据和控制信息来检测程序中的缺陷.需要强调的是,Prefast检测的缺项不仅仅是安全缺陷,但是安全缺陷类型是其检测的最 ...
- [转载] 常用 Java 静态代码分析工具的分析与比较
转载自http://www.oschina.net/question/129540_23043 简介: 本文首先介绍了静态代码分析的基本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代 ...
- .NET 11 个 Visual Studio 代码性能分析工具
原文地址 软件开发中的性能优化对程序员来说是一个非常重要的问题.一个小问题可能成为一个大的系统的瓶颈.但是对于程序员来说,通过自身去优化代码是十分困难的.幸运的是,有一些非常棒的工具可以帮助程序员进行 ...
- 【转载】常用 Java 静态代码分析工具的分析与比较
摘自:http://www.oschina.net/question/129540_23043常用 Java 静态代码分析工具的分析与比较 简介: 本文首先介绍了静态代码分析的基本概念及主要技术,随后 ...
- Springboot学习02-webjars和静态资源映射规则
Springboot学习01-webjars和静态资源映射规则 前言 1-以前我们在IDEA中创建一个项目,添加web依赖包,我们现在是一个web应用,应该在man目录下面有一个webapp文件夹,将 ...
随机推荐
- iOS WKWebView ios9以上版本配置 与 设置UserAgent(用户代理), 解决点击web, 客户端接收不到web事件问题
项目运行在ios9上需要在info.plist文件中配置加入如下信息, App Transport Security Settings Allow Arbitrary Loads = YES < ...
- ASPxgridview 编辑列初始化事件
在初始化编辑咧的时候,给其赋值或者是disable等等.... 贴上代码 protected void master_CellEditorInitialize(object sender, ASPxG ...
- ajax登录请求,无法跳转
没有用form提交数据,用的ajax提交.服务器显示已经登录成功,并且返回了成功代码OK.却无法进行跳转: js代码: $("input[type='submit']").on(& ...
- HDU-1083
Courses Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total S ...
- Intersection of Two Linked Lists——经典问题
Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...
- poj2104 划分树 区间K大 在线 无修改
博主sbit....对于高级数据结构深感无力,然后这些东西在OI竟然烂大街了,不搞就整个人都不好了呢. 于是我勇猛的跳进了这个大坑 ——sbit 区间K大的裸题,在线,无修改. 可以用归并树(\(O( ...
- 解决获取图片实际尺寸(宽高)的bug
需求:获取图片的宽高其实是为了预先做好排版样式布局做准备. 可以利用图片onload事件监听获取图片的宽高属性值.在IE9以下版本只能使用图片的width与height属性,HTMl5中新加入了nat ...
- vue分页tbale小荔枝
首先,动态加载数据 <table class="table table-bordered table-condensed no_margin_bottom jyjg_tab" ...
- Linux上安装MongoDB
使用本教程使用.rpm 软件包在红帽企业Linux或CentOS Linux版本6和7上安装MongoDB Community Edition . 平台支持 本安装指南仅支持64位系统.详细信息请参见 ...
- python3连接使用sqlite3
一直比较喜欢sqlite,业余爱好不需要大型数据库,原来在windows下最常用的就是access,使用很方便,但是linux下没法用,后 来从php+sqlite2开始使用,编程时间很少,代码量很小 ...