敌人的敌人是朋友 并查集_最好是善的敌人

敌人的敌人是朋友 并查集

Picture 6

自测器 (SelfTester)

We develop and promote the PVS-Studio static code analyzer for C, C++, C# and Java. To test the quality of our analyzer we use internal tools, generically called SelfTester. We created a separate SelfTester version for each supported language. It is due to specifics of testing, and it's just more convenient. Thus, at the moment we have three internal SelfTester tools in our company for C\C++, C# and Java, respectively. Further, I'll tell about Windows version of SelfTester for C\C++ Visual Studio projects, calling it simply SelfTester. This tester was the first in line of similar internal tools, it's the most advanced and complex of all.

我们开发和推广适用于C,C ++,C#和Java的PVS-Studio静态代码分析器。 为了测试分析仪的质量,我们使用内部工具,通常称为SelfTester。 我们为每种支持的语言创建了一个单独的SelfTester版本。 这是由于测试的细节所致,更加方便。 因此,目前我们公司拥有三个内部的SelfTester工具,分别用于C \ C ++,C#和Java。 此外,我将介绍Windows C / C ++ Visual Studio项目的SelfTester版本,简称为SelfTester。 该测试器是同类内部工具中的第一款,它是所有工具中最先进,最复杂的。

How does SelfTester work? The idea is simple: take a pool of test projects (we're using real open source projects) and analyze them using PVS-Studio. As a result, an analyzer log is generated for each project. This log is compared with the reference log of the same project. When comparing logs, SelfTester creates a summary of logs comparing in a convenient developer-friendly way.

SelfTester如何工作? 这个想法很简单:收集一组测试项目(我们正在使用真正的开源项目),然后使用PVS-Studio对其进行分析。 结果,为每个项目生成了一个分析器日志。 将此日志与同一项目的参考日志进行比较。 比较日志时,SelfTester会以方便开发人员的方式创建日志摘要以进行比较。

After studying the summary, a developer concludes about changes in the analyzer behavior according to the number and type of warnings, working speed, internal analyzer errors, etc. All this information is very important: it allows you to be aware of how the analyzer copes with its work.

在研究了摘要之后,开发人员根据警告的数量和类型,工作速度,内部分析仪错误等得出分析仪行为变化的结论。所有这些信息非常重要:它使您知道分析仪如何应对与它的工作。

Based on the summary of logs comparison, a developer introduces changes in the analyzer core (for example, when creating a new diagnostic rule) and immediately controls the result of his edits. If a developer has no more issues to a regular log comparing, he makes a current warnings log reference for a project. Otherwise, the work continues.

基于日志比较的摘要,开发人员在分析器核心中进行了更改(例如,在创建新的诊断规则时),并立即控制其编辑结果。 如果开发人员与常规日志比较没有更多问题,那么他将为项目提供当前的警告日志参考 。 否则,工作将继续。

So, the task of SelfTester is to work with a pool of test projects (by the way, there are more than 120 of them for C/C++). Projects for the pool are selected in the form of Visual Studio solutions. It is done so in order to additionally check the analyzer's work on various Visual Studio versions, which support the analyzer (at this point from Visual Studio 2010 to Visual Studio 2019).

因此,SelfTester的任务是使用一组测试项目(顺便说一下,其中有120多个用于C / C ++)。 池的项目以Visual Studio解决方案的形式选择。 这样做是为了额外检查分析器在支持分析器的各种Visual Studio版本上的工作(此时从Visual Studio 2010到Visual Studio 2019)。

Note: further I'll separate the concepts 注意:此外,我将概念 solution and 解决方案project, considering a project as a part of a solution. 项目分开,将项目视为解决方案的一部分。

SelfTester's interface looks as follows:

SelfTester的界面如下所示:

Picture 3

On the left there is a list of solutions, on the right — results of a check for each Visual Studio version.

左边是解决方案的列表,右边是对每个Visual Studio版本的检查结果。

Grey labels «Not supported» indicate that a solution doesn't support a chosen Visual Studio version or it wasn't converted for this version. Some solutions have a configuration in a pool, that indicates a specific Visual Studio version for a check. If a version isn't specified, a solution will be updated for all subsequent Visual Studio versions. An example of such a solution is on the screenshot — «smart_ptr_check.sln» (a check is made for all Visual Studio versions).

灰色标签“不支持”表示解决方案不支持所选的Visual Studio版本或未针对该版本进行转换。 某些解决方案在池中具有配置,该配置指示要检查的特定Visual Studio版本。 如果未指定版本,则将为所有后续Visual Studio版本更新解决方案。 屏幕截图中的一个示例就是这种解决方案-«smart_ptr_check.sln»(对所有Visual Studio版本都进行了检查)。

A green label «OK» indicates that a regular check hasn't detected differences with the reference log. A red label «Diff» indicates about differences. These labels have to be paid special attention. After clicking twice on the needed label, the chosen solution will be opened in a related Visual Studio version. A window with a log of warnings will also be open there. The control buttons at the bottom allow you to rerun the analysis of the selected or all solutions, make the chosen log (or all at once) reference, etc.

绿色标签“确定”表示常规检查未检测到与参考日志的差异。 红色标签“差异”表示差异。 这些标签必须特别注意。 在所需标签上单击两次后,将在相关的Visual Studio版本中打开所选解决方案。 带有警告日志的窗口也将在那里打开。 底部的控制按钮使您可以重新运行所选解决方案或所有解决方案的分析,使所选日志(或一次全部)成为参考,等等。

SelfTester's results are always duplicated in the html report (diffs report)

SelfTester的结果始终在html报告(差异报告)中重复

In addition to GUI, SelfTester also has automated modes for night build runs. However, the usual usage pattern repeated developer runs by a developer during the workday. Therefore, one of the most important SelfTester's characteristics is the speed of working.

除GUI外,SelfTester还具有夜间构建运行的自动化模式。 但是,通常的使用模式是在工作日内由开发人员重复运行。 因此,最重要的SelfTester特征之一就是工作速度。

Why speed matters:

为什么速度很重要:

  1. Each step's performance is quite crucial in terms of night test runs. Obviously, the faster the tests pass, the better. At the moment, the average performance time of SelfTester exceeds 2 hours;

    就夜间试运行而言,每个步骤的性能都至关重要。 显然,测试通过得越快越好。 目前,SelfTester的平均执行时间超过2小时;
  2. When running SelfTester during the day, a developer has to wait less for the result, which increases his workforce productivity.

    白天运行SelfTester时,开发人员必须减少等待结果的时间,从而提高了工作效率。

It was performance speeding up that became the reason for refinements this time.

正是性能提升成为这次改进的原因。

SelfTester中的多线程 (Multi-threading in SelfTester)

SelfTester was initially created as a multithreaded application with the ability to simultaneously test several solutions. The only limitation was that you couldn't simultaneously check the same solution for different Visual Studio versions, because many solutions need to be updated to certain versions of Visual Studio before testing. During the course of it, changes are introduced directly in files of the .vcxproj projects, which leads to errors during parallel running.

SelfTester最初是作为多线程应用程序创建的,能够同时测试多个解决方案。 唯一的限制是您不能同时为不同的Visual Studio版本检查同一解决方案,因为在测试之前,许多解决方案需要更新为Visual Studio的某些版本。 在此过程中,更改直接引入.vcxproj项目的文件中,这会导致并行运行时出错。

In order to make the work more efficient, SelfTester uses an intelligent task scheduler to set a strictly limited value of parallel threads and maintain it.

为了使工作更有效率,SelfTester使用智能任务计划程序来设置并限制并行线程的严格限制值。

The planner is used on two levels. The first one is the level of solutions, it's used to start testing the .sln solution using the PVS-Studio_Cmd.exe utility. The same scheduler, but with another setting of parallelism degree, is used inside PVS-Studio_Cmd.exe (at the source files testing level).

该计划程序有两个级别。 第一个是解决方案级别,它用于开始使用PVS-Studio_Cmd.exe实用工具测试.sln解决方案。 在PVS-Studio_Cmd.exe内部使用了相同的调度程序,但具有另一个并行度设置(在源文件测试级别)。

The degree of parallelism is a parameter that indicates how many parallel threads have to be run simultaneously. Four and eight default values were chosen for the parallelism degree of the solutions and files level, respectively. Thus, the number of parallel threads in this implementation has to be 32 (4 simultaneously tested solutions and 8 files). This setting appears optimal to us for the analyzer work on an eight-core processor.

并行度是一个参数,指示必须同时运行多少个并行线程。 为解决方案和文件级别的并行度分别选择了四个八个默认值。 因此,此实现中的并行线程数必须为32(4个同时测试的解决方案和8个文件)。 对于我们的分析仪在八核处理器上工作而言,此设置对我们来说是最佳的。

A developer can set other values of the parallelism degree himself according to his computer performance or current tasks. If a developer doesn't specify this parameter, the number of logical system processors will be chosen by default.

开发人员可以根据自己的计算机性能或当前任务来设置并行度的其他值。 如果开发人员未指定此参数,则默认情况下将选择逻辑系统处理器的数量。

Note: let's further assume that we deal with the default degree of parallelism. 注意:让我们进一步假设我们处理默认的并行度。

The scheduler LimitedConcurrencyLevelTaskScheduler is inherited from System.Threading.Tasks.TaskScheduler and refined to provide the maximum parallelism level when working over ThreadPool. Inheritance hierarchy:

调度程序LimitedConcurrencyLevelTask​​Scheduler继承自System.Threading.Tasks.TaskScheduler,并经过改进以在使用ThreadPool时提供最大的并行度。 继承层次结构:

LimitedConcurrencyLevelTaskScheduler : PausableTaskScheduler
{ .... }
PausableTaskScheduler: TaskScheduler
{ .... }
PausableTaskScheduler allows you to pause task performance, and in addition to this, PausableTaskScheduler允许您暂停任务性能,此外, LimitedConcurrencyLevelTaskScheduler provides intellectual control of the tasks queue and scheduling their performance, taking into account the parallelism degree, the scope of the scheduled tasks and other factors. A scheduler is used when running LimitedConcurrencyLevelTask​​Scheduler还提供了对任务队列的智能控制,并考虑了并行度,已调度任务的范围和其他因素来调度其性能。 运行 LimitedConcurrencyLevelTaskScheduler tasks. LimitedConcurrencyLevelTask​​Scheduler任务时使用调度程序。

完善的理由 (Reasons for Refinements)

The process described above has a drawback: it is not optimal when dealing with solutions of different sizes. And the size of solutions in the test pool is very diverse: from 8KB to 4GB — the size of a folder with a solution and from 1 up to several thousands of source code files in each one.

上述过程有一个缺点:在处理不同大小的解决方案时不是最佳的。 而在测试池解决方案的尺寸是非常多样:从8KB到4GB -一个可以解决的文件夹的大小,并从1到几千的源代码文件中的每一个。

The scheduler puts solutions on the queue simply one after another, without any intelligent component. Let me remind you that by default not more than four solutions can be tested simultaneously. If four large solutions are currently tested (the number of files in each is more than eight), it's assumed that we work effectively because we use as many threads as possible (32).

调度程序将解决方案简单地一个接一个地放入队列,而没有任何智能组件。 让我提醒您,默认情况下最多可以同时测试四个解决方案。 如果当前测试了四个大型解决方案(每个解决方案中的文件数都超过八个),则可以认为我们有效地工作是因为我们使用了尽可能多的线程(32个)。

But let's imagine a rather frequent situation, when several small solutions are tested. For example, one solution is large and contains 50 files (maximum number of threads will be used), while other three solutions contain three, four, five files each. In this case, we'll only use 20 threads (8 + 3 + 4 + 5). We get underutilization of processor's time and reduced overall performance.

但是,让我们想象一下在测试几个小型解决方案时出现的一种相当频繁的情况。 例如,一个解决方案很大,包含50个文件(将使用最大线程数),而其他三个解决方案则分别包含三个,四个,五个文件。 在这种情况下,我们将仅使用20个线程(8 + 3 + 4 + 5)。 我们未充分利用处理器时间并降低了整体性能。

Note:in fact, the bottleneck is usually the disk subsystem, not the processor. 注意 :实际上,瓶颈通常是磁盘子系统,而不是处理器。

改进之处 (Improvements)

The improvement that is self-evident in this case is ranking of tested solutions list. We need to get optimal usage of the set number of simultaneously performed threads (32), by passing to test projects with the correct number of files.

在这种情况下不言而喻的改进是测试解决方案列表的排名。 通过传递给具有正确数量文件的测试项目,我们需要对一定数量的同时执行线程(32)进行最佳利用。

Let's consider again our example of testing four solutions with the following number of files in each: 50, 3, 4 and 5. The task that checks a solution of three files is likely to work out the fastest. It would be best to add a solution with eight or more files instead of it (in order to use maximum from the available threads for this solution). This way, we'll utilize 25 threads at once (8 +

让我们再次考虑测试四个具有以下文件数量的解决方案的示例:50、3、4和5。检查三个文件的解决方案的任务可能最快。 最好添加一个包含八个或更多文件的解决方案,而不是添加文件(以便为此解决方案使用最大可用线程数)。 这样,我们将一次利用25个线程(8 +

8 (8)

+ 4 + 5). Not bad. However, seven threads are still uninvolved. And here comes the idea of another refinement, which is to remove the four threads limit on testing solutions. Because we now can add not one, but several solutions, utilizing 32 threads. Let's imagine that we have two more solutions of three and four files each. Adding these tasks will completely close the «gap» of unused threads, and there will be32 (8 + 8 + 4 + 5 +

+ 4 + 5)。 不错。 但是,仍然不涉及七个线程。 接下来是另一种改进的想法,即消除测试解决方案的四个线程限制。 因为我们现在可以利用32个线程添加一个解决方案,而不是几个解决方案。 让我们想象一下,我们还有另外两个分别包含三个和四个文件的解决方案。 添加这些任务将完全关闭未使用线程的“间隙”,并且将有32(8 + 8 + 4 + 5 +

3 (3)

+

+

4 (4)

) of them.

)。

Hopefully the idea is clear. In fact, the implementation of these improvements also didn't require much effort. Everything was done in one day.

希望这个想法很明确。 实际上,实施这些改进也不需要太多的努力。 一切都在一天之内完成。

We needed to rework the task class: inheriting from System.Threading.Tasks.Task and assignment of the field «weight». We use a simple algorithm to set weight to a solution: if the number of files is less than eight, the weight is equal to this number (for example, 5). If the number is greater or equal to eight, the weight will be equal to eight.

我们需要重做任务类:从System.Threading.Tasks.Task继承并分配字段“ weight”。 我们使用一种简单的算法为解决方案设置权重:如果文件数少于八个,则权重等于该数字(例如5)。 如果数字大于或等于8,则权重将等于8。

We also had to elaborate the scheduler: teach it to choose solutions with needed weight in order to reach maximum value of 32 threads. We also had to allow more than four threads for simultaneous solutions testing.

我们还必须详细说明调度程序:教导它选择具有所需权重的解决方案,以达到32个线程的最大值。 我们还必须允许四个以上的线程用于同时进行解决方案测试。

Finally, we needed a preliminary step to analyze all solutions in the pool (evaluation using MSBuild API) to evaluate and set weight of solutions (getting numbers of files with source code).

最后,我们需要一个初步步骤来分析池中的所有解决方案(使用MSBuild API进行评估),以评估和设置解决方案的权重(使用源代码获取文件数量)。

结果 (Result)

I think after such a long introduction you've already guessed that nothing came of it.

我认为经过这么长时间的介绍,您已经猜不到一切。

Picture 12

It's good though that the improvements were simple and fast.

很好的是,这些改进既简单又快速。

Here comes that part of the article, where I'm going to tell you about what «got us into many troubles» and all things related to it.

这里是文章的这一部分,在这里我将告诉您什么“使我们陷入许多麻烦”以及与之相关的所有事物。

副作用 (Side Effects)

So, a negative result is also a result. It turned out that the number of large solutions in the pool far exceeds the number of small ones (less than eight files). In this case, these improvements don't have a very noticeable effect, as they are almost invisible: testing small projects takes teeny-tiny amount of time comparing to time, needed for large projects.

因此,负面结果也是结果。 事实证明,池中大型解决方案的数量远远超过小型解决方案(少于八个文件)的数量。 在这种情况下,这些改进不会产生非常明显的效果,因为它们几乎是看不见的:与大型项目所需的时间相比,测试小型项目所花费的时间很少。

However, we decided to leave the new refinement as «non-disturbing» and potentially useful. In addition, the pool of test solutions is constantly replenished, so in the future, perhaps, the situation will change.

但是,我们决定将新的改进保留为“不打扰”并且可能有用。 此外,不断补充测试解决方案的资源,因此在将来,情况可能会改变。

And then…

然后…

Picture 5

One of the developers complained about the SelfTester's crash. Well, life happens. To prevent this error from being lost, we created an internal incident (ticket) with the name «Exception when working with SelfTester». The error occurred while evaluating the project. Although a large number of windows with errors indicated the problem back in the error handler. But this was quickly eliminated, and over the next week nothing crashed. Suddenly, another user complained about SelfTester. Again, the error of a project evaluation:

一名开发人员抱怨SelfTester崩溃。 好吧,生活发生了。 为避免丢失此错误,我们创建了一个内部事件(故障单),名称为“使用SelfTester时的异常”。 评估项目时发生错误。 尽管有错误的窗口很多,但在错误处理程序中却指出了问题。 但这很快就消除了,在接下来的一周中没有任何崩溃。 突然,另一个用户抱怨SelfTester。 再次,项目评估的错误:

Picture 8

This time the stack contained much useful information — the error was in the xml format. It's likely, that when handling the file of the Proto_IRC.vcxproj project (its xml representation) something happened to the file itself, that's why XmlTextReader couldn't handle it.

这次堆栈包含许多有用的信息-错误是xml格式。 处理Proto_IRC.vcxproj项目的文件(以xml表示)时,文件本身可能发生了某些情况,这就是XmlTextReader无法处理它的原因。

Having two errors in a fairly short period of time made us take a closer look at the problem. In addition, as I said above, SelfTester is very actively used by developers.

在相当短的时间内出现两个错误使我们仔细研究了这个问题。 另外,正如我上面所说,SelfTester被开发人员非常积极地使用。

To begin with, we analyzed the last crash. Sad to say, we found nothing suspicious. Just in case we asked developers (SelfTester users) to keep an eye out and report about possible errors.

首先,我们分析了上次崩溃。 可悲的是,我们没有发现任何可疑的。 以防万一我们要求开发人员(SelfTester用户)保持警惕并报告可能的错误。

Important point: the erroneous code was reused in SelfTester. It was originally used to evaluate projects in the analyzer itself (PVS-Studio_Cmd.exe). That's why attention to the problem has grown. However, there were no such crashes in the analyzer.

要点:错误代码已在SelfTester中重用。 它最初用于评估分析仪本身中的项目( PVS-Studio_Cmd.exe )。 这就是为什么人们越来越关注这个问题的原因。 但是,分析仪中没有此类崩溃。

Meanwhile, the ticket about problems with SelfTester was supplemented with new errors:

同时,有关SelfTester问题的票证还添加了新的错误:

Picture 9

再次 XmlException again. Obviously, there are competing threads somewhere that work with reading and writing project files. SelfTester works with projects in the following cases: XmlException 。 显然,某些地方存在竞争线程,这些线程可用于读写项目文件。 在以下情况下,SelfTester可以与项目一起使用:
  1. Projects evaluation in the course of preliminary calculation of solutions' weights: a new step that initially aroused suspicion;

    在初步计算解决方案权重的过程中进行项目评估:最初引起怀疑的新步骤;
  2. Updating projects to the needed Visual Studio versions: is performed right before testing (projects don't interfere) and it mustn't affect the working process.

    将项目更新为所需的Visual Studio版本:是在测试之前(项目不会干扰)执行的,并且不得影响工作过程。
  3. Projects evaluation during testing: a well-established thread-safe mechanism, reused from PVS-Studio_Cmd.exe;

    测试过程中的项目评估:完善的线程安全机制,可从PVS-Studio_Cmd.exe中重用;

  4. Restoring project files (replacing modified .vcxproj files with initial reference files) when exiting from SelfTester, because project files can update to needed Visual Studio versions during the work. It's a final step, which has no impact on other mechanisms.

    从SelfTester退出时还原项目文件(用初始参考文件替换修改的.vcxproj文件),因为在工作期间项目文件可以更新到所需的Visual Studio版本。 这是最后一步,对其他机制没有影响。

Suspicion fell on the new code added for optimization (weight calculation). But its code investigation showed that if a user runs the analysis right after the start of SelfTester, the tester always correctly waits till the end of the pre-evaluation. This place looked safe.

怀疑是为了优化(权重计算)而添加的新代码。 但是它的代码调查显示,如果用户在SelfTester启动后立即运行分析,则测试人员始终可以正确地等待直到预评估结束。 这个地方看起来很安全。

Again, we were unable to identify the source of the problem.

同样,我们无法确定问题的根源。

(Pain)

All next month SelfTester continued to crash ever and again. The ticket kept filling with data, but it wasn't clear what to do with this data. Most crashes were with the same XmlException. Occasionally there was something else, but on the same reused code from PVS-Studio_Cmd.exe.

下个月,SelfTester继续崩溃一次又一次。 凭单不断填充数据,但不清楚如何处理此数据。 大多数崩溃都带有相同的XmlException。 有时还有其他事情,但是在PVS-Studio_Cmd.exe的相同重用代码上。

Picture 1

Traditionally, internal tools aren't imposed very high requirements, so we kept puzzling out SelfTester's errors on a residual principle. From time to time, different people got involved (during the whole incident six people worked on the problem, including two interns). However, we had to be distracted by this task.

传统上,内部工具的要求不是很高,因此我们一直在以残留原则来混淆SelfTester的错误。 有时,会有不同的人参与进来(整个事件中,有六个人解决了这个问题,包括两名实习生)。 但是,我们必须分心这项任务。

Our first mistake. In fact, at this point we could've solved this problem once and for all. How? It was clear that the error was caused by a new optimization. After all, before it everything worked well, and the reused code clearly cannot be so bad. In addition, this optimization hadn't brought any benefit. So what had to be done? 我们的第一个错误。 实际上,在这一点上,我们可以一劳永逸地解决此问题。 怎么样? 很明显,该错误是由新的优化引起的。 毕竟,在一切正常之前,重用的代码显然不会那么糟糕。 此外,这种优化没有带来任何好处。 那该怎么办呢? Remove this optimization. As you probably understand, it wasn't done. We continued to work on the problem, which we created ourselves. We continued searching for the answer: «HOW???» How does it crash? It seemed to be written correctly. 删除此优化。 正如您可能理解的那样,它尚未完成。 我们继续致力于解决我们自己创造的问题。 我们继续寻找答案:«HOW ???» 它如何崩溃? 它似乎写得正确。 Our second mistake. 我们的第二个错误。 Other people got involved in solving the problem 其他人也参与解决问题 . It's a very, very big mistake. Not only didn't it solve the problem but also required additional wasted resources. Yes, new people brought new ideas, but it took a lot of working time to implement (for nothing) these ideas. At some point, we had our interns writing test programs emulating evaluation of one and the same project in different threads with parallel modification of a project in another project. It didn't help. We only found out that MSBuild API was thread-safe inside, which we've already known. We also added mini dump auto saving when the 这是一个非常非常大的错误。 它不仅不能解决问题,而且还需要额外的资源浪费。 是的,新人们带来了新的想法,但要花大量的时间来实现(毫无用处)这些想法。 在某个时候,我们让实习生编写测试程序,以模拟对一个项目和同一项目在不同线程中的评估,并在另一个项目中并行修改一个项目。 它没有帮助。 我们仅发现MSBuild API在内部是线程安全的,这一点我们已经知道。 当 XmlException exception occurs. We had someone who was debugging all this. Poor guy! There were discussions, we did other needless things. XmlException异常发生时,我们还添加了小型转储自动保存功能。 我们有一个调试这一切的人。 可怜的家伙! 经过讨论,我们做了其他不必要的事情。 Finally, out third mistake. Do you know how much time has passed from the moment the SelfTester problem occurred to the point when it was solved? Well, you can count yourself. The ticket was created on 17/09/2018 and closed on 20/02/2019. There were more than 40 comments! Guys, that's a lot of time! We 最后,找出第三个错误。 您是否知道从SelfTester问题发生到解决这一问题已经过去了多少时间? 好吧,你可以数一数。 门票于2018年9月17日创建,于2019年2月20日关闭。 有40多个评论! 伙计们,这是很多时间! 我们 allowed ourselves to be busy for five months with THIS. At the same time we were busy supporting Visual Studio 2019, adding the Java language support, introducing MISRA C/C++ standard, improving the C# analyzer, actively participating in conferences, writing a bunch of articles, etc. All these activities received less time of developers because of a stupid error in SelfTester. 让自己在THIS忙了五个月。 同时,我们正忙于支持Visual Studio 2019,添加Java语言支持,引入MISRA C / C ++标准,改进C#分析器,积极参加会议,撰写大量文章等。所有这些活动花费的时间更少开发人员,因为SelfTester中有一个愚蠢的错误。

Folks, learn from our mistakes and never do like this. We won't either.

亲朋好友,请从我们的错误中吸取教训,并且永远不要这样做。 我们也不会。

That's it, I'm done.

就是这样,我完成了。

Picture 15

Okay, it was a joke, I'll tell you what was the problem with SelfTester :)

好的,这是个玩笑,我会告诉你SelfTester出了什么问题:)

答对了! (Bingo!)

Fortunately, there was a person among us with clear-eyed view (my colleague Sergey Vasiliev), who just looked at the problem from a very different angle (and also — he got a bit lucky). What if it's ok inside the SelfTester, but something from the outside crashes the projects? Usually we had nothing launched with SelfTester, in some cases we strictly controlled the execution environment. In this case, this very «something» could be SelfTester itself, but a different instance.

幸运的是,我们中间有一个眼睛清晰的人(我的同事谢尔盖·瓦西里耶夫(Sergey Vasiliev)),他只是从非常不同的角度看问题(而且,他也很幸运)。 如果SelfTester内部没问题,但外面的东西会使项目崩溃,该怎么办? 通常,我们没有使用SelfTester启动任何东西,在某些情况下,我们严格控制执行环境。 在这种情况下,这个“某物”可能是SelfTester本身,但是是一个不同的实例。

When exiting SelfTester, the thread that restores project files from references, continues to work for a while. At this point, the tester might be launched again. Protection against the simultaneous runs of several SelfTester instances was added later and now looks as follows:

退出SelfTester时,从引用还原项目文件的线程将继续工作一段时间。 此时,测试器可能会再次启动。 稍后添加了针对多个SelfTester实例同时运行的保护,现在看起来如下所示:

Picture 16

But at that point we didn't have it.

但是那时我们还没有。

Nuts, but true — during almost six months of torment no one paid attention to it. Restoring projects from references is a fairly fast background procedure, but unfortunately not fast enough not to interfere with the re-launch of SelfTester. And what happens when we launch it? That's right, calculating the weights of solutions. One process rewrites .vcxproj files while another tries to read them. Say hi to XmlException.

坚果,但事实如此—在将近六个月的酷刑中,没有人关注它。 从引用恢复项目是一个相当快的后台过程,但是不幸的是,它的速度还不够快,不会干扰SelfTester的重新启动。 当我们启动它时会发生什么? 没错,计算解决方案的权重。 一个进程重写.vcxproj文件,而另一个进程尝试读取它们。 向XmlException打个招呼

Sergey found out all this when he added the ability to switch to a different set of reference logs to the tester. It became necessary after adding a set of MISRA rules in the analyzer. You can switch directly in the interface, while the user sees this window:

Sergey在向测试人员添加切换到另一组参考日志的功能时发现了所有这些情况。 在分析器中添加了一组MISRA规则后,变得很有必要。 您可以在用户看到此窗口的同时直接在界面中切换:

Picture 14

After that, SelfTester restarts. And earlier, apparently, users somehow emulated the problem themselves, running the tester again.

之后, SelfTester重新启动。 显然,更早之前,用户以某种方式自己模拟了问题,然后再次运行测试仪。

谴责和结论 (Blamestorming and Conclusions)

Of course, we removed (that is, disabled) the optimization created earlier. In addition, it was much easier than doing some kind of synchronization between re-starts of the tester by itself. And everything started to work perfectly, as before. And as an additional measure, we added the above protection against the simultaneous launch of the tester.

当然,我们删除了(即禁用了)先前创建的优化。 此外,它比在重新启动测试仪本身之间进行某种同步要容易得多。 和以前一样,一切开始正常运行。 作为一项附加措施,我们增加了防止同时启动测试仪的上述保护措施。

I've already written above about our main mistakes when searching for the problem, so enough of self-flagellation. We're human beings, so we might be wrong. It is important to learn from your own mistakes and draw conclusions. The conclusions from this case are quite simple:

我已经在上面写过关于搜索问题时的主要错误的信息,这足以引起自我鞭ation。 我们是人类,所以我们可能错了。 重要的是要从自己的错误中吸取教训并得出结论。 这个案例的结论很简单:

  • We should monitor and estimate the task complexity;

    我们应该监视和估计任务的复杂性;
  • Sometimes we need to stop at some point;

    有时我们需要在某个时候停下来;
  • Try to look at the problem more broadly. Over time one can get tunnel vision of the case whereas it requires fresh perspective.

    尝试更广泛地看待问题。 随着时间的流逝,人们可以获得对案件的洞察力,而它需要新的视角。
  • Don't be afraid to delete old or unnecessary code.

    不要害怕删除旧的或不必要的代码。

That's it, this time I'm definitely done. Thank you for reading up to the end. I wish you bugless code!

就是这样,这一次我肯定完成了。 感谢您的阅读。 希望您没有错误的代码!

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

敌人的敌人是朋友 并查集

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值