静态代码分析如何在GameDev空间中提供帮助

image1.png


游戏业并没有停滞不前,并且每天都在发展。随着行业的发展,开发的复杂性也在增加:其中包含更多的代码和更多的错误。因此,现代游戏项目需要特别注意代码的质量。今天,我们将讨论提高代码质量的方法之一-静态分析,以及PVS-Studio在大型(且不仅是)游戏项目的开发中如何提供帮助。



近年来,作为一名程序员,我要做的最重要的事情是积极地进行静态代码分析。与我所预防的数百个严重错误相比,它更有价值,这是改变了我对软件可靠性和代码的看法。品质。 ”- John Carmack



我们已经与大型游戏开发商合作了很多年,在这段时间里,我们已经为游戏行业做了很多有趣而有用的事情。考虑到我们来自游戏行业的客户名单,这不足为奇。我们为客户提供积极的支持:我们帮助他们将PVS-Studio集成到他们自己的开发过程中,修复分析仪发现的错误,甚至订购特殊功能。



此外,我们在GameDev方向上做了很多独立的分析仪开发工作,并且通过向人们介绍各种视频游戏中发现的有趣错误,我们还普及了PVS-Studio。



自然,并非没有有趣的故事。本文将讨论其中一些故事。



PVS-Studio和Unity



image2.png


我们推广产品的方法之一是撰写有关审查开源项目的文章。每个人都会从这些文章中受益:读者可以在一个熟悉的项目中查看有趣的错误并为自己学习一些新知识,我们有机会以真实的代码展示PVS-Studio的工作,项目开发人员可以了解错误并提前进行修复。



我们与Unity的初次熟识始于2016年,当时该游戏引擎的开发人员将几个组件,库和演示的源代码发布到了其官方存储库中。自然,我们不能忽略这种“好吃”的情况,而是想写一篇有关检查已布置代码的文章。



然后我们发现Unity3D代码(当时以这种方式调用了引擎)的质量很高,但是,在编写文章时,我们设法找到了很多严重的错误



两年后,又发生了另一件事-这次Unity开发人员发布了引擎本身的代码和编辑器以打开访问权限。就像以前一样,我们无法通过并检查引擎的源代码。并有充分的理由:我们还发现了一些有趣的错误



但是,撰写文章远非一切。我们将继续致力于PVS-Studio,GameDev是我们最重要的开发领域之一。因此,我们希望Unity游戏开发人员能够对其项目进行最好的分析。



对我们来说,提高Unity项目分析质量的步骤之一是为Unity Scripting API中定义的方法编写注释。



方法注释是PVS-Studio中使用的一种特殊机制。它使您可以为分析仪提供有关特定方法所需的所有信息。它由分析仪的开发人员自己(即由我们)以特殊代码编写。



该信息可以是完全不同的种类。例如:方法如何影响传递给它的参数,是否可以分配内存以及是否返回必须处理的值。因此,注释使分析仪可以更好地理解方法的逻辑,从而使其能够检测到新的和更复杂的错误。



我们已经编写了各种不同的注释(例如,用于System命名空间中的方法),并且很高兴为它们添加Unity Scripting API中的方法注释。



我们开始将带有评估的注释添加到注释列表中。有几种方法?首先应该注释哪些?总共有很多方法,我们决定从注释最常用的方法开始。



搜索流行方法的步骤如下:首先,我们从GitHub收集了一个使用Unity功能的项目库,然后使用自写的实用程序(基于Roslyn)对我们感兴趣的方法的调用进行了计数。结果,我们得到了一个类列表,这些类的方法最常用:



  • UnityEngine.Vector3
  • UnityEngine.Mathf
  • UnityEngine.Debug
  • UnityEngine.GameObject
  • UnityEngine.Material
  • UnityEditor.EditorGUILayout
  • UnityEngine.Component
  • UnityEngine.Object
  • UnityEngine.GUILayout
  • UnityEngine.Quaternion
  • ...


接下来,需要注释这些类的方法。我们创建了一个测试项目,并深入研究了文档,以获取有关这些方法的尽可能多的信息。例如,我们尝试传递null作为各种参数,以查看程序的行为。



在进行此类检查时,会定期发现有趣的未记录信息-我们甚至还发现了引擎中的几个有趣的错误。因此,当运行这样的代码时:



MeshRenderer renderer = cube.GetComponent<MeshRenderer>();
Material m = renderer.material;
List<int> outNames = null;
m.GetTexturePropertyNameIDs(outNames);


Unity编辑器本身直接崩溃(至少在版本2019.3.10f1中)。当然,不可能有人会编写这样的代码,但是可以通过运行这样的脚本来“打倒” Unity编辑器这一事实很有趣。



因此,注释被写入。开始分析后,我们立即发现了新的触发器。例如,分析器检测到对GetComponent方法的奇怪调用



void OnEnable()
{
  GameObject uiManager = GameObject.Find("UIRoot");

  if (uiManager)
  {
    uiManager.GetComponent<UIManager>();
  }
}


分析器警告: V3010需要使用功能“ GetComponent”的返回值。 -当前的UIEditorWindow.cs中的其他内容22 GetComponent



方法,即使其名称也暗示了一定值的返回。合理地假设应该以某种方式使用此值。现在(由于有了新的注释),分析器知道该方法的这种“孤立”调用可能表明存在逻辑错误,并向您发出警告。



这与添加新注释后出现在我们的测试项目集中的唯一触发因素相差甚远-我将不赘述其余内容,以免使本文过大。最主要的是,现在使用PVS-Studio开发Unity项目可以使您编写更安全,更整洁的代码而没有错误。



如果您想通过Unity方法的注释更详细地了解我们的工作,可以在我们的文章中做到这一点:PVS-Studio分析器如何开始在Unity项目中发现更多错误



虚幻引擎4



image3.png


早在2014年,虚幻引擎4的开发人员向公众发布了该引擎的源代码时,我们根本无法解决这个项目,并撰写了一篇有关它的文章。引擎开发人员喜欢这篇文章,并修复了我们发现的错误。但这对我们来说还不够,我们决定尝试将分析仪的许可证出售给Epic Games。



Epic Games有兴趣使用PVS-Studio改进其引擎,因此我们达成了一项协议:我们自己修复虚幻引擎代码,以使分析仪不会对此发出任何警告,并且Epic Games的家伙购买了我们的许可,此外奖励我们所做的工作。



为什么需要修复所有警告?关键是,只要纠正错误就可以从静态分析中获得最大的收益。通常,当您第一次检查项目时,会收到几百(有时是数千)警告。在所有这些分析器警告中,为新编写的代码发出的警告很容易丢失。



乍一看,这个问题很容易解决:您只需要坐下来完全绕过整个报告,逐步纠正错误即可。但是,这种方法虽然更直观,但可能会花费时间。使用抑制文件的方法更加方便快捷。



禁止文件是PVS-Studio特殊功能,它使您可以“隐藏”分析器触发器的特殊文件。在这种情况下,隐藏的警告将不会出现在后续日志中:可以单独查看它们。



在第一次检查后收到大量触发器后,您可以单击几下,将所有检测到的触发器添加到抑制文件中,然后在分析器进行下一次检查时,您将收到没有单个触发器的干净日志。



现在不再记录旧的警告,您可以在出现新警告时轻松地发现它。我们编写了代码->使用分析器对其进行了检查->看到了新的警告->修复了错误。这是您最大程度地利用分析仪的方式。



同时,不要忘记抑制文件中的肯定内容:它们与以前一样,它们可能包含有关严重错误和漏洞的警告。因此,您应该定期返回这些警告并减少其数量。



当然,这种情况很方便,但是Epic Games的开发人员希望立即修复他们的代码,然后将其交给我们。



然后我们开始工作。检查项目代码后,我们发现1821一级警告Level_1和Level_2。解析这么多的警告需要认真的工作,为了简化整个过程,我们在CI服务器上设置了持续的代码分析。



它看起来像这样:虚幻引擎4的当前版本每天晚上都在我们的服务器上编译,并且在构建后立即自动启动分析。因此,当我们的人早上来上班时,他们总是手头上有一份新的分析仪报告,以便他们跟踪纠正警告的进度。另外,这样的系统使得可以通过在服务器上手动运行来随时检查构建的稳定性。



整个过程花了我们17个工作日。纠正警告的时间表如下:



image4.png


实际上,该图不能完全反映我们的工作。修复所有警告后,我们又等待了两天,等待它们接受我们的最新拉动请求。一直以来,我们继续自动检查Unreal Engine的最新版本,然后继续为其补充新代码。你觉得怎么样?在这两天中,PVS-Studio在代码中发现了另外四个错误!其中之一特别严重,并可能导致不确定的行为。



当然,我们也修复了这些错误。现在,虚幻引擎开发人员只需要做一件事:以与我们相同的方式配置他们的自动分析。从那时起,他们开始每天看到针对新编写的代码发出的警告。这使他们甚至在出现的那一刻(在开发的最早阶段)就可以修复代码中的错误



您可以在官方虚幻引擎博客我们的网站上了解有关我们如何处理虚幻引擎代码的更多信息



分析各种游戏



image5.png


我是否提到过我们检查了各种开源项目并撰写了有关它们的文章?因此,我们只有很多类似的有关游戏项目的文章!我们已经写过有关VVVVVV空间工程师命令与征服osu等游戏!甚至(非常古老的文章)Doom 3。我们还汇总了视频游戏行业最有趣的10个错误。



我们还检查了大多数知名的开源引擎。除了Unity和Unreal Engine 4外,我们还可以看到GodotBulletAmazon LumberyardCry Engine V等项目还有很多其他



所有这些最好的部分是,我们描述的许多错误随后都是由项目开发人员自己修复的。很高兴您正在开发的工具正在为世界带来真正,可见和切实的好处。



您可以在博客的特殊页面上看到我们所有与视频游戏开发相关的文章的列表



结论



我的短文到此结束。希望您有一个干净,正确的代码,并且没有错误和错误!



对静态分析感兴趣?您要检查项目中的错误吗?尝试PVS-Studio







如果您想与讲英语的读者分享本文,请使用翻译链接:George Gribkov。静态代码分析如何在GameDev行业中提供帮助



All Articles