矢量网络分析仪测量功分器_如何在遗留项目中引入静态代码分析器而又不劝阻团队...

矢量网络分析仪测量功分器

It is easy to try a static code analyzer. But it requires skills to introduce it in the development of an old large project. If the approach is incorrect, the analyzer can add work, slow down development, and demotivate the team. Let's briefly discuss how to properly integrate static analysis into the development process and start using it as part of CI/CD.

尝试使用静态代码分析器很容易。 但是它需要技巧来将其引入旧的大型项目中。 如果方法不正确,则分析人员可能会增加工作量,减慢开发速度并激励团队。 让我们简短地讨论如何将静态分析正确地集成到开发过程中,并开始将其用作CI / CD。

介绍 (Introduction)

Recently I got interested in the post "Getting Started With Static Analysis Without Overwhelming the Team". On the one hand, this is a decent article that is worth reading. On the other hand, it seems to me that it didn't provide a complete answer on how to safely adopt static analysis in a project with a large amount of legacy code. The article says that you can put up with technical debt and work only with new code, but there it doesn't cover the question what to do with this technical debt later.

最近,我对“ 静态分析入门而又不压倒团队 ”感兴趣。 一方面,这是一篇不错的文章,值得一读。 另一方面,在我看来,它没有提供关于如何在具有大量旧代码的项目中安全地采用静态分析的完整答案。 文章说,您可以忍受技术债务,只能使用新代码,但是这里没有涵盖如何处理此技术债务的问题。

Our PVS-Studio team offers our own view on this topic. Let's look at how the problem of embedding a static code analyzer arises in general, how to overcome this problem, and how to gradually eliminate technical debt seamlessly.

我们的PVS-Studio团队对此主题提供了自己的看法。 让我们看看嵌入静态代码分析器的问题通常是如何产生的,如何克服这个问题,以及如何逐步消除技术负担。

问题 (Problematics)

It is usually easy to start the analyzer and see how it works [1]. You can see some intriguing bugs, or even scary potential vulnerabilities in the code. You can even fix something, but after this many programmers give up.

通常很容易启动分析仪并查看其工作原理[ 1 ]。 您可以在代码中看到一些有趣的错误,甚至可怕的潜在漏洞。 您甚至可以修复某些问题,但此后许多程序员放弃了。

All static analyzers issue false positives. This is a particularity of the static code analysis methodology, and nothing can be done about it. So this is an unsolvable problem, which is confirmed by the Rice's theorem [2]. Machine learning algorithms will not help either [3]. If even a person can't always tell whether a particular code is wrong, you shouldn't expect this from the program :).

所有静态分析器都会发出误报。 这是静态代码分析方法的特殊性,对此无能为力。 因此,这是一个无法解决的问题,赖斯定理[ 2 ]证实了这一点。 机器学习算法也无济于事[ 3 ]。 如果甚至一个人也不能总是说出某个特定的代码是否错误,那么您就不应从程序中指望这一点:)。

False positives aren't a problem if the static analyzer is already configured:

如果已经配置了静态分析器,则误报不是问题:

  • Irrelevant rule sets are disabled;

    不相关的规则集被禁用;
  • Individual irrelevant diagnostics are disabled;

    个别无关的诊断将被禁用;
  • If we are talking about C or C++, macros containing specific constructs (that cause useless objects to appear in every place where such macros are used) are marked up;

    如果我们谈论的是C或C ++,则标记包含特定构造的宏(这些宏会导致无用的对象出现在使用此类宏的每个位置);
  • Custom functions that perform actions similar to system functions are marked up (custom analog of memcpy or printf) [4];

    标记了执行类似于系统功能的动作的定制功能( memcpyprintf的定制模拟)[ 4 ];

  • False positives are selectively disabled using the comments;

    使用注释有选择地禁用误报。
  • And so on.

    等等。

In this case, we can expect a low level of false positives on the order of 10-15% [5]. In other words, 9 out of 10 analyzer warnings will indicate a real problem in the code, or at least «code with a strong smell». Agree, this scenario is extremely pleasant, and the analyzer becomes a real friend of the programmer.

在这种情况下,我们可以预期误报率较低,约为10-15%[ 5 ]。 换句话说,每10个分析仪警告中有9个将指示代码中的实际问题,或者至少指示“具有强烈气味的代码”。 同意,这种情况非常令人愉快,并且分析器成为程序员的真正朋友。

In reality, in a large project, the initial picture will be quite different. The analyzer issues hundreds or thousands of warnings for legacy code. It is impossible to quickly get, which of these warnings are relevant and which are not. It's not rational to sit down and start dealing with all these warnings, since the main work in this case will stop for days or weeks. As a rule, the team can't indulge in following such a scenario. Also there will be a huge number of diffs that spoil the history of changes. A quick mass fixing of such a large number of fragments in the code will inevitably result in new typos and errors.

实际上,在一个大型项目中,初始情况会大不相同。 分析器会针对旧代码发出成百上千的警告。 不可能快速获得这些警告中哪些与警告无关。 坐下来开始处理所有这些警告是不合理的,因为这种情况下的主要工作将停止数天或数周。 通常,团队不能沉迷于这种情况。 此外,还会有大量的差异破坏变化的历史。 快速大量固定代码中的大量片段将不可避免地导致新的错字和错误。

Most importantly, such a feat in the fight against warnings makes little sense. You have to admit that since the project has been successfully running for many years, most of the critical errors in it have already been fixed. Yes, these fixes were very expensive, you had to debug them, get negative user reviews about bugs, and so on. A static analyzer would help fix many of these errors at the code writing stage, quickly and cheaply. But at the moment, these errors are fixed anyway, and the analyzer mainly detects non-critical errors in the old code. This code may not be used, it may be used very rarely, and an error in it may not lead to noticeable consequences. It is possible that somewhere the shadow of the button is the wrong color, but this doesn't prevent anyone from using the product.

最重要的是,在与警告的斗争中取得如此壮举毫无意义。 您必须承认,由于该项目已经成功运行了很多年,所以其中的大多数关键错误已经得到修复。 是的,这些修复非常昂贵,您必须对其进行调试,获得有关错误的负面用户评论,等等。 静态分析器将有助于在代码编写阶段快速,廉价地修复许多这些错误。 但是目前,这些错误无论如何都已修复,并且分析器主要检测旧代码中的非严重错误。 该代码可能无法使用,可能很少使用,并且其中的错误可能不会导致明显的后果。 按钮阴影的某处可能是错误的颜色,但这不会阻止任何人使用该产品。

Of course, even minor mistakes are still mistakes. And sometimes the error can hide a real vulnerability. However, it seems a dubious idea to give up everything and spend days/weeks dealing with defects that don't reveal themselves obviously.

当然,即使是小错误也仍然是错误。 有时该错误会隐藏一个真正的漏洞。 但是,放弃所有内容并花费几天/几周的时间来处理那些显然不会显露出来的缺陷,这似乎是一个可疑的想法。

Programmers keep looking and looking at all these warnings on the old working code… And they think: let's do without static analysis. Let's go write a new useful feature.

程序员一直在查看旧的工作代码上的所有这些警告…并且他们认为:让我们无需进行静态分析。 让我们编写一个新的有用功能。

In their own way, they are right. They think they should get rid of all these warnings first. Only after this they will be able benefit from regular use of the code analyzer. Otherwise, the new warnings will simply sink into the old ones, and no one will pay attention to them.

以他们自己的方式,他们是对的。 他们认为应该首先摆脱所有这些警告。 只有这样,他们才能从定期使用代码分析器中受益。 否则,新警告只会陷入旧警告中,而没有人会注意它们。

This is the same analogy as with compiler warnings. It's no accident that it's recommended to have 0 compiler warnings. If there are 1000 warnings, then when they become 1001, no one will pay attention to this, and it is not clear where to look for this newest warning.

这与编译器警告类似。 建议0个编译器警告绝非偶然。 如果有1000个警告,那么当它们变为1001时,没有人会注意这一点,并且不清楚在哪里可以找到最新的警告。

The worst part of this story is if someone from upstairs forces you to use static code analysis at this point. This only demotivates the team, since from their point of view there will be an additional bureaucratic complexity that only hinders their work. The analyzer reports will not be viewed by anyone, and all usage will only be «on paper». That is, formally, analysis is built into the DevOps process, but in practice, this doesn't benefit anyone. We have heard detailed stories from conference visitors when chatting at the booths. Such experience can discourage programmers from using static analysis tools for a long time, if not always.

这个故事最糟糕的部分是,如果楼上有人强迫您此时使用静态代码分析。 这只会使团队失去动力,因为从他们的角度来看,还会增加官僚主义的复杂性,只会阻碍他们的工作。 任何人都不会查看分析仪报告,并且所有用法都只能在“纸上”上进行。 也就是说,正式而言,分析已内置到DevOps流程中,但实际上,这不会使任何人受益。 我们在摊位上聊天时听到了与会者的详细故事。 这样的经验可能会阻止程序员长时间(即使不是一直使用)使用静态分析工具。

分析仪介绍和消除技术债务 (Analyzer introduction and elimination of technical debt)

In fact, there is nothing difficult or scary about integrating static analysis even in a large old project.

实际上,即使在一个大型的旧项目中,集成静态分析也没有什么困难或可怕的事情。

CI / CD (CI/CD)

Moreover, the analyzer can be immediately made part of the continuous development process. For example, the PVS-Studio distribution has utilities for convenient viewing of the report in the format you need, and notifications to developers who wrote problematic sections of code. For those who are more interested in running PVS-Studio from CI/CD systems, I recommend reading the corresponding section of the documentation and a series of articles:

而且,分析仪可以立即成为持续开发过程的一部分。 例如,PVS-Studio发行版具有实用程序,可方便地以您需要的格式查看报告,并通知编写有问题的代码部分的开发人员。 对于那些对从CI / CD系统运行PVS-Studio更感兴趣的人,我建议阅读文档的相应部分以及一系列文章:

But let's return to the issue of a large number of false positives in the first stages of implementing code analysis tools.

但是,让我们回到实施代码分析工具的第一阶段存在大量误报的问题。

冻结现有技术债务并使用新警告 (Freezing existing technical debt and working with new warnings)

Modern commercial static analyzers allow you to review only new warnings that appear in new or modified code. The implementation of this mechanism differs, but the essence is the same. In the PVS-Studio static analyzer, this functionality is implemented as follows.

现代的商用静电分析仪仅允许您查看以新代码或修改的代码出现的新警告。 该机制的实现有所不同,但本质是相同的。 在PVS-Studio静态分析仪中,此功能的实现如下。

To quickly start using static analysis, we suggest that PVS-Studio users apply the mass warning suppression mechanism [6]. The general idea is the following. Imagine, the user has started the analyzer and received many warnings. Since a project that has been developed for many years, is alive, still developing and bringing money, then most likely there won't be many warnings in the report indicating critical defects. In other words, critical bugs have already been fixed due to more expensive ways or with the help of feedback from customers. Thus, everything that the analyzer now finds can be considered technical debt, which is impractical to try to eliminate immediately.

为了快速开始使用静态分析,我们建议PVS-Studio用户应用质量警告抑制机制[ 6 ]。 总体思路如下。 想象一下,用户已启动分析仪并收到许多警告。 由于已经开发了多年的项目仍然存在,并且仍在开发中并且仍在赚钱,因此报告中很可能不会有很多警告指出严重缺陷。 换句话说,由于更昂贵的方式或在客户反馈的帮助下,关键错误已得到修复。 因此,分析仪现在发现的所有东西都可以视为技术债务,试图立即消除是不切实际的。

You can tell PVS-Studio to consider all these warnings irrelevant so far (to postpone the technical debt for later), and not to show them any more. The analyzer creates a special file where it stores information about as-yet-uninteresting errors. From now on, PVS-Studio will issue warnings only for new or modified code. By the way, it's all implemented in a very smart way. If an empty line is added at the beginning of a file, the analyzer will size up the situation as if nothing has really changed and will remain quiet. You can put the markup file in the version control system. Even though the file is large, it's not a problem, as there's no need to upload it very often.

您可以告诉PVS-Studio到目前为止,将所有这些警告视为无关紧要的(将技术债务推迟到以后),而不再显示它们。 分析器创建一个特殊的文件,在其中存储有关尚未引起关注的错误的信息。 从现在开始,PVS-Studio将仅针对新代码或修改后的代码发出警告。 顺便说一下,所有这些都是以非常聪明的方式实现的。 如果在文件的开头添加了空行,则分析器将调整情况的大小,好像什么都没有真正更改并且将保持安静。 您可以将标记文件放入版本控制系统中。 即使文件很大,也不是问题,因为不需要经常上传。

From this point, developers will see only warnings related to newly written or modified code. So you can start using the analyzer, as they say, from the next day. You can get back to technical debt later and gradually correct errors and tweak the analyzer.

从这一点来看,开发人员将仅看到与新编写或修改的代码有关的警告。 因此,您可以从第二天开始使用他们所说的分析仪。 您可以稍后再找技术债,逐步纠正错误并调整分析仪。

So, the first problem with introducing the analyzer in a large old project is solved. Now let's figure out what to do with technical debt.

因此,解决了在大型旧项目中引入分析仪的第一个问题。 现在让我们弄清楚如何处理技术债务。

错误修复和重构 (Error fixing and refactoring)

The simplest and most natural thing is to spend some time analyzing massively suppressed analyzer warnings and gradually deal with them. In some cases you should fix bugs in code, in others — perform refactoring to tell the analyzer that the code is not problematic. A simple example:

最简单,最自然的方法是花一些时间分析被大量抑制的分析仪警告,并逐步对其进行处理。 在某些情况下,您应该修复代码中的错误,在其他情况下,请执行重构以告知分析器代码没有问题。 一个简单的例子:

if (a = b)

Most C++ compilers and analyzers complain about such code, since there is high probability that they actually wanted to write (a == b). But there is an unspoken agreement, and this is usually noted in the documentation, that if there are additional brackets, it is considered that the programmer deliberately wrote such code, and there is no need to trigger a warning for it. For example, the PVS-Studio documentation for the V559 (CWE-481) diagnostic clearly states that the next line will be considered correct and safe:

大多数C ++编译器和分析器都抱怨这样的代码,因为他们实际上很想编写(a == b) 。 但是有一个不言而喻的协议,并且通常在文档中指出,如果有其他括号,则认为程序员是故意编写了这样的代码,因此无需对其发出警告。 例如,用于V559(CWE-481)诊断的PVS-Studio文档明确指出,下一行将被认为是正确和安全的:

if ((a = b))

Another example: Is break forgotten in this C++ code or not?

另一个示例:此C ++代码中是否忘记了中断

case A:
  foo();
case B:
  bar();
  break;

The PVS-Studio analyzer will issue the V796 (CWE-484) warning here. This may not be an error, and then you should give the analyzer a hint by adding the [[fallthrough]] attribute or, for example, __attribute__((fallthrough)):

PVS-Studio分析仪将在此处发出V796(CWE-484)警告。 这可能不是错误,然后您应该通过添加[[fallthrough]]属性或例如__attribute __((fallthrough))来向分析器提供提示:

case A:
  foo();
  [[fallthrough]];
case B:
  bar();
  break;

We can say that code changes of such kind don't really fix errors. Yes, this is true, but there are still two useful consequences. First, the analyzer report gets rid of false positives. Secondly, the code becomes more understandable for people who are involved in its maintenance. Which is extremely significant! For the sake of this alone, it is already worth going for small refactoring, so that the code becomes clearer and easier to maintain. Since the analyzer doesn't understand whether «break» is needed or not, it will also be unclear to fellow programmers.

我们可以说这种代码更改并不能真正解决错误。 是的,这是正确的,但仍有两个有用的后果。 首先,分析仪报告消除了误报。 其次,该代码对于参与其维护的人员而言更易于理解。 这非常重要! 仅出于此目的,进行小型重构已经值得,因此代码变得更清晰,更易于维护。 由于分析器不了解是否需要“中断”,因此其他程序员也不清楚。

In addition to bug fixes and refactoring, you can selectively suppress false warnings of the analyzer. You can disable some irrelevant diagnostics. For example, some consider V550 warnings about comparing float/double values meaningless. And some consider them significant and worthy of study [7]. It is up to the development team to decide which warnings are relevant and which are not.

除了错误修复和重构之外,您还可以有选择地抑制分析仪的错误警告。 您可以禁用一些不相关的诊断。 例如,有些人认为有关比较浮点/双精度值的V550警告毫无意义。 有些人认为它们很重要,值得研究[ 7 ]。 由开发团队决定哪些警告相关,哪些警告无关。

There are other ways to suppress false warnings. For example, the macro markup which was mentioned earlier. All this is described in more detail in the documentation. The most vital thing is to understand that if you gradually and consistently work with false positives, there is nothing scary about them. The vast majority of uninteresting warnings disappear after configuration, leaving only places that really require careful study and some changes in the code.

还有其他抑制误报的方法。 例如,前面提到的宏标记。 所有这些都在文档中有更详细的描述。 最重要的是要了解,如果您逐步并持续地使用误报,就不会感到恐惧。 绝大多数无趣的警告在配置后都会消失,仅留下真正需要仔细研究并在代码中进行一些更改的地方。

Also, we always help our clients set up PVS-Studio if there are any difficulties. Moreover, there were cases when we ourselves eliminated false warnings and corrected errors [8]. Just in case, I decided to mention that this option of extended cooperation is also possible :).

此外,如果有任何困难,我们将始终帮助我们的客户设置PVS-Studio。 此外,在某些情况下,我们自己消除了错误警告并纠正了错误[ 8 ]。 以防万一,我决定提一下这种扩展合作的选择也是可行的:)。

棘轮法 (Ratchet method)

There is another interesting approach of gradually improving the quality of the code by eliminating static analyzer warnings. The bottom line is that the number of warnings can only decrease.

还有另一种有趣的方法,可以通过消除静态分析器警告来逐步提高代码质量。 底线是警告的数量只能减少。

Рисунок 3

The number of warnings issued by the static analyzer gets counted. Quality gate is configured in such a way that now you can only commit code that doesn't increase the number of triggers. As a result, the process of consistent reducing of the warnings number starts by configuring the analyzer and editing errors.

静态分析器发出的警告数量得到计数。 质量门的配置方式使得您现在只能提交不会增加触发器数量的代码。 结果,通过配置分析仪和编辑错误开始不断减少警告数量的过程。

Even if a person wants to cheat a little and decides to pass quality gate not by eliminating warnings in their new code, but by improving the old third-party code, it's not a big deal. All the same, the ratchet turns in one direction and gradually the number of defects will decrease. Even if a person doesn't want to edit their own new defects, they will still have to improve something in the neighboring code. At some point, the easy ways to reduce the number of warnings end, and there comes a moment when real errors will be fixed.

即使一个人想要作弊并决定通过质量门检查,不是通过消除新代码中的警告,而是通过改进旧的第三方代码,这并不是什么大问题。 同样,棘轮向一个方向旋转,并且缺陷的数量将逐渐减少。 即使一个人不想编辑自己的新缺陷,他们仍将不得不改善相邻代码中的某些内容。 在某种程度上,减少警告数量的简便方法结束了,并且有时会修复实际错误。

This methodology is described in more detail in a very interesting article by Ivan Ponomarev "Introduce Static Analysis in the Process, Don't Just Search for Bugs with It", which I recommend to read to anyone who is interested in improving the quality of code.

Ivan Ponomarev在一篇非常有趣的文章“ 在过程中引入静态分析,而不只是使用它来寻找错误 ”中对此方法进行了更详细的描述,我建议阅读给任何对提高代码质量感兴趣的人。

结论 (Conclusion)

I hope that after checking out this article, readers will be more friendly to static analysis tools and will want to introduce them in the development process. If you still have questions, we are always ready to consult users of our PVS-Studio static analyzer and help with its implementation.

我希望阅读完本文后,读者将对静态分析工具更加友好,并希望在开发过程中介绍它们。 如果您仍有疑问,我们随时准备咨询 PVS-Studio静态分析仪的用户并提供实施帮助。

There are other typical doubts about whether a static analyzer can really be convenient and useful. I tried to dispel most of these doubts in the publication «Why You Should Choose the PVS-Studio Static Analyzer to Integrate into Your Development Process» [9].

对于静态分析仪是否真的方便和有用,还有其他一些典型的疑问。 我试图消除出版物“为什么要选择PVS-Studio静态分析仪以集成到您的开发过程中”中的大多数疑问[ 9 ]。

Thank you for your attention! Come download and try the PVS-Studio analyzer.

感谢您的关注! 快下载并尝试使用PVS-Studio分析仪。

其他连结 (Additional links)

  1. Andrey Karpov. How to quickly check out interesting warnings given by the PVS-Studio analyzer for C and C++ code?

    安德烈·卡波夫(Andrey Karpov)。 如何快速检查出PVS-Studio分析仪针对C和C ++代码给出的有趣警告?

  2. Wikipedia. Rice's theorem.

    维基百科。 赖斯定理

  3. Andrey Karpov, Victoria Khanieva. Machine Learning in Static Analysis of Program Source Code.

    安德烈·卡波夫(Andrey Karpov),维多利亚·哈尼耶娃(Victoria Khanieva)。 机器学习在程序源代码静态分析中的应用

  4. PVS-Studio. Documentation. Additional diagnostics configuration.

    PVS-Studio。 文档。 其他诊断配置

  5. Andrey Karpov. Characteristics of PVS-Studio Analyzer by the Example of EFL Core Libraries, 10-15% of False Positives.

    安德烈·卡波夫(Andrey Karpov)。 以EFL核心库为例,PVS-Studio分析仪的特性为10-15%的误报

  6. PVS-Studio. Documentation. Mass suppression of analyzer warnings.

    PVS-Studio。 文档。 质量抑制分析仪警告

  7. Ivan Andryashin. How We Tried Static Analysis on Our X-Ray Endovascular Surgery Training Simulator Project.

    伊万·安德拉辛(Ivan Andryashin)。 X射线血管内手术训练模拟器项目如何尝试静态分析

  8. Paul Eremeev, Svyatoslav Razmyslov. How the PVS-Studio Team Improved Unreal Engine's Code.

    保罗·埃雷梅耶夫(Paul Eremeev),斯维亚托斯拉夫·拉兹米洛夫(Svyatoslav Razmyslov) PVS-Studio团队如何改进虚幻引擎的代码

  9. Andrey Karpov. Why You Should Choose the PVS-Studio Static Analyzer to Integrate into Your Development Process.

    安德烈·卡波夫(Andrey Karpov)。 为什么要选择PVS-Studio静态分析仪以集成到您的开发过程中

翻译自: https://habr.com/en/company/pvs-studio/blog/507504/

矢量网络分析仪测量功分器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值