开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

蛮牛译馆

关注:565

当前位置:游戏蛮牛 技术专区 蛮牛译馆

查看: 927|回复: 11

[Unity教程] 在Unity3D的开源组件中讨论Errors

[复制链接]  [移动端链接]
排名
3833
昨日变化
1

32

主题

126

帖子

724

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
47400
好友
9
蛮牛币
952
威望
0
注册时间
2014-9-30
在线时间
118 小时
最后登录
2017-9-19

蛮牛译员

QQ
发表于 2017-3-31 13:36:17 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
本帖最后由 木木妖妖 于 2017-3-31 13:38 编辑

到目前为止,是一个发展迅速并且最有前途的游戏引擎。不时地,开发人员将新的库和组件上传到官方存储库,其中许多直到最近才成为开源项目。不幸的是,Unity3D开发团队允许公众分析的只有一些组件,库,和使用的项目演示,同时保持其代码块的状态是关闭的。在这篇文章中,在PVS Studio静态分析器的帮助下,我们将试图在这些组件中找到错误和输入错误。

Introduction 引言
我们决心检查分析那些在Unity3D developer team's official repository能找到源代码的组件,库以及使用c#写的demo。

1. UI System- system for GUI development.
UI System- 用于GUI开发的系统.
2. Networking- system for implementing multiplayer mode.
3. MemoryProfiler - system for profiling resources in use.
4. XcodeAPI- component for interacting with the Xcode IDE.
5. PlayableGraphVisualizer - system for project execution visualization.
6. UnityTestTools - Unity3D testing utilities (no Unit tests included).
7. AssetBundleDemo - project with AssetBundleServer's source files and demos for AssetBundle system.
8. AudioDemos - demo projects for the audio system.
9. NativeAudioPlugins - audio plugins (we are only interested in the demos for these plugins).
10. GraphicsDemos - demo projects for the graphics system.


我希望我们可以看看引擎内核本身的源文件,但不幸的是,除了开发者自己,目前还没有其他任何人访问它。所以,我们今天在操作台上得到的只是引擎源文件的一小部分.。比起以前笨拙的GUI系统,我们更有兴趣使用UI系统设计实现灵活的GUI,以及网络库,在UNet版本之前,为我们提供全部的服务。


我们也对MemoryProfiler很感兴趣,这是一个强大而又灵活的工具,用于资源和负载分析。

Errors and suspicious fragments found 发现错误和可疑的碎片
所有分析仪发出的警告被分为3级:

1. High - almost certainly an error. 高级别-几乎可以肯定是一个错误
2. Medium - possible error or typo.中级-可能是错误或者输入错误
3. Low - unlikely error or typo.低级-不像是错误或者输入错误

我们只讨论这篇文章中的高级别和中等级别的.。

下表列出了我们检查过的项目列表,并分析了所有项目的统计信息.。“Project name”和“Number of LOC”这两列是不言自明的,但“Issued Warnings”这一列需要解释一下。它包含了分析器发出的所有警告信息。正面警告直接或间接地指向实际代码中的错误或拼写错误。错误警告,或误报,则是那些解释正确的代码被作为错误。正如我已经说过的,所有警告分为3级.。我们将只讨论高级别和中等级别的警告,因为低级别主要是处理信息或不太可能的错误.。

在检查的10个项目中,分析器发出了16个高级别警告,其中75%正确地指向代码中的实际错误,以及18个中等级别的警告,其中39%正确地指向代码中的实际缺陷.。代码绝对是高质量的,如发现LOC数误差的平均比例是每2000行代码有一个错误,这是一个很好的结果。


现在,我们正在做的统计,让我们看看有什么错误以及输入错误可以设法找到。

Incorrect regular expression 不正确的正则表达式
V3057构造函数中存在无效的正则表达式模式。检查第一个参数。AssetBundleDemo ExecuteInternalMono.cs 48
[AppleScript] 纯文本查看 复制代码
private static readonly Regex UnsafeCharsWindows = 
  new Regex("[^A-Za-z0-9\\_\\-\\.\\:\\,\\/\\@\\\\]"); // <=


当试图使用这个模式实例化Regex类,一个System.Argumentexception异常类将抛出以下消息:

这些消息表明使用的模式是不正确的,Regex类不能用它初始化。程序员在设计这个模式的时候,一定犯了错误。

Possible access to an object using a null reference  使用空指针访问对象

V3080可能是空引用。仔细检测t.staticfieldbytes”。MemoryProfiller CrawledDataUnpacker.cs 20
.... = packedSnapshot.typeDescriptions.Where(t =>
  t.staticFieldBytes != null & t.staticFieldBytes.Length > 0 // <=)....

检查对象是否为空后访问对象。然而,这是访问的检查结果,这可能会导致抛出NullReferenceException。程序员必须有预期的使用条件运算符(&&)却输入错误,写成了逻辑与运算符(&)。

Accessing an object before a null check 在检查对象不为空之前就访问对象

V3095 ’uv2.gameObject'对象在使用它之前被证实为空。检查行:1719,1731。UnityEngine.Networking NetworkServer.cs 1719。

[AppleScript] 纯文本查看 复制代码
if (uv2.gameObject.hideFlags == HideFlags.NotEditable ||
    uv2.gameObject.hideFlags == HideFlags.HideAndDontSave)
  continue;....if (uv2.gameObject == null)
  continue;



首先访问对象,然后才对其进行空检查。如果对象的引用被发现是空的,在检查之前,我们几乎肯定会得到NullReferenceException。

· V3095 ' m_HorizontalScrollbarRect’对象在使用它之前未进行空检查。检查这些行:214,220。UnityEngine.UI ScrollRect.cs 214
· V3095 m_VerticalScrollbarRect对象在使用它之前未进行空检查。检查这些行:215,221.UnityEngine.UI ScrollRect.cs 215

具有相同条件的两个if语句以及在该块中的无条件返回语句.

这是一个很有趣的问题,这是一个很好的例证来说明复制粘贴会犯的错误;一个输入错误的经典例子。
V3021 有两个具有相同的条件表达式if语句。第一个if语句包含有返回的函数。这意味着第二个if的声明是毫无意义的UnityEngine.UI StencilMaterial.cs 64
[AppleScript] 纯文本查看 复制代码
if (!baseMat.HasProperty("_StencilReadMask")){
  Debug.LogWarning(".... _StencilReadMask property", baseMat);
  return baseMat;}if (!baseMat.HasProperty("_StencilReadMask")) // <={
  Debug.LogWarning(".... _StencilWriteMask property", baseMat);
  return baseMat;}


肯定是程序员复制粘贴代码片段后,但忘记更改条件.。


基于这样的错误,我想说的第二次检查是为了看起来像这样:
if (!baseMat.HasProperty("_StencilWriteMask"))

Instantiating an exception class without further using the instance 实例化一个异常类但没有进一步的使用实例

V3006 创建对象而不使用它。“throw”这个关键词可能忘记写了: throw new ApplicationException(FOO). AssetBundleDemo AssetBundleManager.cs 446
[AppleScript] 纯文本查看 复制代码
if (bundleBaseDownloadingURL.ToLower().StartsWith("odr://")){#if ENABLE_IOS_ON_DEMAND_RESOURCES
  Log(LogType.Info, "Requesting bundle " + ....);
  m_InProgressOperations.Add(
    new AssetBundleDownloadFromODROperation(assetBundleName)
  );#else
  new ApplicationException("Can't load bundle " + ....); // <=#endif}


ApplicationException被创建了但不以任何方式使用它。程序员必须要抛出一个异常,但忘记添加throw关键字时,形成异常
Unused arguments in a string formatting method  字符串格式化的函数中未使用的参数

我们都知道,用于字符串格式化的 {N} 格式项的数目必须与传递给该方法的参数的数目相对应.。
V3025 格式不正确。当调用WriteLine函数时出现不同数量的项目格式。不使用的参数:port. AssetBundleDemo AssetBundleServer.cs 59
Console.WriteLine("Starting up asset bundle server.", port); // <=Console.WriteLine("Port: {0}", port);Console.WriteLine("Directory: {0}", basePath);


从这个代码的逻辑来看,程序员似乎忘记了第一行中的参数。从技术的角度来说,这个输入错误不是主要的,,它不会产生任何错误,但它仍然没有意义。

A loop that may become infinite under certain conditions 在一定条件下循环可能变成无限循环

V3032在这种表达上等待是不可靠的,编译器可以优化一些变量。使用volatile var变量或同步的基本类型来避免这个。AssetBundleDemo AssetBundleServer.cs 16

[AppleScript] 纯文本查看 复制代码
Process masterProcess = Process.GetProcessById((int)processID);while (masterProcess == null || !masterProcess.HasExited) // <={
  Thread.Sleep(1000);}


程序员必须有预期的循环迭代来完成外部过程,但没有考虑到这样一个事实,masterprocess变量最初可能有价值,如果过程中未发现存在空值,这会导致无限循环。为了使该算法正常工作,您需要在每次迭代期间使用其标识符访问进程.:
[AppleScript] 纯文本查看 复制代码
while (true) {
  Process masterProcess = Process.GetProcessById((int)processID);
  if (masterProcess == null || masterProcess.HasExited) // <=
    break;
  Thread.Sleep(1000);}


Unsafe event initialization不安全event初始化


该分析仪检测到一个可能不安全的调用事件处理程序,这可能会导致抛出NullReferenceException。

V3083 'unload'事件不安全的调用,NullReferenceException是有可能的。在调用前将事件分配给局部变量。 AssetBundleDemo AssetBundleManager.cs 47
[AppleScript] 纯文本查看 复制代码
internal void OnUnload(){
  m_AssetBundle.Unload(false);
  if (unload != null)
    unload(); // <=}



在这个代码中,unload 字段被测试为NULL,然后这个事件被调用。空检查允许您避免在事件被调用时抛出异常,即使是在没有订阅的情况下。


想象一下,事件有一个订阅者。在空检查和调用事件处理程序之间的任意一处,用户可能订阅事件,例如,在另一个线程。在这种情况下,为了保护您的代码,您可以按以下方式编写:
[AppleScript] 纯文本查看 复制代码
internal void OnUnload(){
  m_AssetBundle.Unload(false);
  unload?.Invoke(); // <=}


该解决方案将帮助您确保对NULL事件的测试以及调用其句柄将被执行为一个语句,使事件调用更安全.。
Part of a logical expression always true or false 逻辑表达式的一部分总是真或假

V3063条件表达式的一部分永远是假的:connid<0。UnityEngine.Networking ConnectionArray.cs 59

[AppleScript] 纯文本查看 复制代码
public NetworkConnection Get(int connId){
  if (connId < 0)
  {
    return m_LocalConnections[Mathf.Abs(connId) - 1];
  }
  if (connId < 0 || connId > m_Connections.Count) // <=
  {
    ...
    return null;
  }
  return m_Connections[connId];}


在get函数中第二次检查时connid<0表达式总是不成立,因为函数总是在第一次检查后终止。因此,第二次评估这个表达式是没有意义的.。


分析仪发现一个类似的错误。
[AppleScript] 纯文本查看 复制代码
public bool isServer{
  get
  {
    if (!m_IsServer)
    {
        return false;
    }
    return NetworkServer.active && m_IsServer; // <=
  }}



你肯定知道这个属性可以简化为以下:
[AppleScript] 纯文本查看 复制代码
public bool isServer{
  get
  {
    return m_IsServer && NetworkServer.active;
  }}


Besides these two examples, there are 6 more issues of that kind:除了这两个例子外,还有6个问题:
· V3022 Expression 'm_Peers == null' is always false. UnityEngine.Networking NetworkMigrationManager.cs 710
· V3022 Expression 'uv2.gameObject == null' is always false. UnityEngine.Networking NetworkServer.cs 1731
· V3022 Expression 'newEnterTarget != null' is always true. UnityEngine.UI BaseInputModule.cs 147
· V3022 Expression 'pointerEvent.pointerDrag != null' is always false. UnityEngine.UI TouchInputModule.cs 227
· V3063 A part of conditional expression is always true: currentTest != null. UnityTestTools TestRunner.cs 237
· V3063 A part of conditional expression is always false: connId < 0. UnityEngine.Networking ConnectionArray.cs 86


Conclusion 结论


就像其他的项目一样,这其中包含了大量的错误和输入错误。正如你可能已经注意到的,PVS Studio特别善于捕捉输入错误。
也欢迎你来试试我们的静态分析器,无论C / C++ / C #编写的代码,自己的或别人的项目都可以用它。
最后谢谢大家的阅读。也许你的代码没有错误哦。



回复

使用道具 举报

排名
277
昨日变化

28

主题

751

帖子

3244

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
6108
好友
15
蛮牛币
3116
威望
0
注册时间
2013-10-22
在线时间
903 小时
最后登录
2017-9-22

社区QQ达人七夕浪漫情人

QQ
发表于 2017-4-1 08:48:01 | 显示全部楼层
虽然看不懂,还是占个楼

回复 支持 反对

使用道具 举报

6蛮牛粉丝
1233/1500
排名
2189
昨日变化
1

0

主题

420

帖子

1233

积分

Rank: 6Rank: 6Rank: 6

UID
164723
好友
0
蛮牛币
2511
威望
0
注册时间
2016-8-29
在线时间
311 小时
最后登录
2017-9-22
发表于 2017-4-1 09:43:37 | 显示全部楼层
66666666666666666666666666

回复 支持 反对

使用道具 举报

6蛮牛粉丝
1330/1500
排名
1662
昨日变化
1

1

主题

414

帖子

1330

积分

Rank: 6Rank: 6Rank: 6

UID
56496
好友
0
蛮牛币
3770
威望
0
注册时间
2014-11-19
在线时间
295 小时
最后登录
2017-9-20
发表于 2017-4-1 13:43:00 | 显示全部楼层
占楼。。。。。。

回复

使用道具 举报

7日久生情
2587/5000
排名
167
昨日变化

2

主题

143

帖子

2587

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
40098
好友
0
蛮牛币
13084
威望
0
注册时间
2014-8-15
在线时间
652 小时
最后登录
2017-8-31
QQ
发表于 2017-4-1 20:54:27 | 显示全部楼层
Nice job     !

回复 支持 反对

使用道具 举报

5熟悉之中
645/1000
排名
2969
昨日变化
17

4

主题

73

帖子

645

积分

Rank: 5Rank: 5

UID
127539
好友
0
蛮牛币
3192
威望
0
注册时间
2015-11-1
在线时间
190 小时
最后登录
2017-9-23
QQ
发表于 2017-4-3 09:01:47 | 显示全部楼层
非常好,很有帮助
[发帖际遇]: iaming 在网吧通宵,花了 2 蛮牛币. 幸运榜 / 衰神榜

回复

使用道具 举报

4四处流浪
395/500
排名
4444
昨日变化
1

0

主题

55

帖子

395

积分

Rank: 4

UID
210353
好友
0
蛮牛币
1701
威望
0
注册时间
2017-3-7
在线时间
96 小时
最后登录
2017-9-18
发表于 2017-4-3 11:15:20 | 显示全部楼层
66666666666666666666666666666666666666666

回复 支持 反对

使用道具 举报

3偶尔光临
261/300
排名
8871
昨日变化
4

2

主题

36

帖子

261

积分

Rank: 3Rank: 3Rank: 3

UID
216680
好友
1
蛮牛币
434
威望
0
注册时间
2017-4-7
在线时间
133 小时
最后登录
2017-9-23
发表于 2017-4-10 09:22:35 | 显示全部楼层
66666666666666666666666666

回复 支持 反对

使用道具 举报

3偶尔光临
152/300
排名
10006
昨日变化
1

0

主题

39

帖子

152

积分

Rank: 3Rank: 3Rank: 3

UID
45315
好友
2
蛮牛币
347
威望
0
注册时间
2014-9-17
在线时间
41 小时
最后登录
2017-9-14
发表于 2017-4-18 11:09:14 | 显示全部楼层
谢谢分享

回复

使用道具 举报

排名
37860
昨日变化
38

0

主题

47

帖子

51

积分

Rank: 2Rank: 2

UID
218693
好友
0
蛮牛币
65
威望
0
注册时间
2017-4-20
在线时间
3 小时
最后登录
2017-4-22
发表于 2017-4-21 14:04:44 | 显示全部楼层
error使问题 不过warning嘛,就不是我们考虑的问题啦嘿嘿嘿

回复 支持 反对

使用道具 举报

5熟悉之中
504/1000
排名
3712
昨日变化
14

0

主题

83

帖子

504

积分

Rank: 5Rank: 5

UID
210517
好友
0
蛮牛币
1780
威望
0
注册时间
2017-3-7
在线时间
121 小时
最后登录
2017-9-23
发表于 2017-4-25 11:25:00 | 显示全部楼层
谢谢分享
[发帖际遇]: 一个袋子砸在了 黑名單上有你 头上,黑名單上有你 赚了 1 蛮牛币. 幸运榜 / 衰神榜

回复

使用道具 举报

6蛮牛粉丝
1240/1500
排名
2466
昨日变化

2

主题

173

帖子

1240

积分

Rank: 6Rank: 6Rank: 6

UID
44036
好友
0
蛮牛币
653
威望
0
注册时间
2014-9-8
在线时间
625 小时
最后登录
2017-9-23
发表于 2017-5-25 11:54:30 | 显示全部楼层
兄弟啊,文笔有待提高啊

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

快速回复 返回顶部 返回列表