游戏开发论坛

 找回密码
 立即注册
搜索
查看: 8508|回复: 0

Debug经验总结:优化、程序员和概率

[复制链接]

1万

主题

1万

帖子

3万

积分

论坛元老

Rank: 8Rank: 8

积分
36572
发表于 2016-5-16 15:08:59 | 显示全部楼层 |阅读模式
QQ截图20160516150019.png

  GameRes游资网授权发布 文 /顾煜

  时间有关的Bug

  所有的console平台,都有一个邪恶的要求:需要做Aging Test。简单来说,就是这些游戏机游戏是要放在店里面卖的,可能商家会把试玩游戏放在外面,很久都没有人玩,你的游戏不能Crash,否则顾客想玩的时候发现游戏Crash了,不会怪罪开发者,而是会认为这个主机不稳定。所以游戏机厂商都要求开发商的游戏要长时间运行不能Crash,通常都要求8个小时左右。我们一般的做法就是,在很久没有检测到玩家的手柄输入信息以后,就进入一个小的死循环,把画面暗下来作屏保状,循环里面只检测输入,有输入就退出这个状态。因为主逻辑不动,复杂的代码都不运行,自然就安全。

  看似简单的aging test,被时间温柔的手抚过,死机了运行的游戏,愁白了开发者的头发。

  那天来了这么一个bug,描述便很科幻很文学,说在某一个场景,有山有水有敌人的地方,主角躲在某个敌人无法攻击的地方,敌人和坦克都会不停地开火。测试兄弟做完这一切便无情地离去,留游戏主角在那里看一夜云起云落,流弹共长天一色。第二天早上一来,操作主角一转身,就Crash了。有词为证:蓦然回首,bug却在灯火阑珊处。

  我也不惊慌,打开VC,Attach到Crash的Xbox360 kit,一看,是更新某个旗帜(softbody做的)的时候,旗帜的Bounding Box太大,被assert掉了。Bounding Box本不该这么大的,看了看所有的顶点,位置都离原点很远。为什么呢?Softbody旗帜更新的时候,会有约束处理,每帧都会把顶点往中间拉一下,让顶点们团结在原点周围。

  第一步自然是试着重现,每天下班就照描述方法重现,机器开着回家,试了几天,终于可以稳定重现了,每次Crash也是同一个地方。

  静下心来,认认真真读了一遍Softbody的顶点更新代码,觉得没什么问题,只好加了些日志,打印几个顶点的坐标。第二天果然又Crash了,输出了1G多的文本日志,在pc查看日志。发现中间部分顶点位置都很正常,直到Crash前最后几帧才急剧变大,最后触发assert。

  下班前又设好环境,第二天在触发Crash前,加好了条件断点,当顶点x坐标大于特定值的时候就断下来。然后操作主角转身,VC马上停下了代码执行。仔细看看,找到了原因。原来Softbody会受到外力,比如手雷或炮弹的爆炸,然后把外力加到顶点上面,改变一下顶点的位置。另外,我们有优化,对于看不见的Softbody,我们不会去更新它的顶点,这样可以快一些。问题在于,每一次那辆坦克开炮,都会炸到那面旗帜,我们就不停地把那个冲量加到了旗帜受力上面。通常每次更新Softbody我们会把受力加到顶点上面,然后把那个变量清零准备接受下一帧的冲量。但这次很不幸,由于更新的优化,这个Softbody在主角背后,没有被更新,那个记录受力的矢量没有清零。经过一个晚上的炮轰,积累了很大的值,主角一转身,Softbody被看见,就更新,巨大冲量的矢量呼啸而来,更新了顶点数据,导致顶点被更新到很遥远的地方了。

  知道原因就好办了,在加冲量的时候,设个上限,超过上限部分一律忽视即可。改动,测了几个晚上,似乎正常,收工。


  可得结论:优化靠不住

  造成最大损失的bug

  2003年,PS2时代,我们用Unreal做一个FPS游戏。PS2性能太低,导致我们游戏多人玩的时候,作Server的那个玩家帧数很低,几乎无法玩。

  我们针对这个问题作了AI高层、物理底层、网络通信层的代码优化,最后,在开发人员这里,似乎能够支持8个玩家了。

  于是我们让测试人员来测4v4,可是他们每次都说性能不理想。在发布最终版本前两天,我们紧急决定,不支持4v4了,改成3v3,这样性能就没问题了。程序员总是这么睿智,老板总是这么英明。

  在做Master版本前的最后一天晚上,远处传来某个程序员撕心裂肺的惨叫:"Release版本下面的代码优化没有打开!"原来如此,某人某次为了便于调试,把Release里面的代码优化关了,然后他不小心又上传了这个项目配置文件。我们测试的版本比较老,都是开着优化的,所以4v4没有问题,做版本给测试人员测的时候用了最新版本,性能就不行了。

  既然没打开优化,打开不就皆大欢喜了?没那么简单,打开以后优化的执行文件会多占用2M的内存,PS2上面内存本来就很少,我们的运行时留的内存只有1M。如果早些发现,还可以让关卡制作和美工去省点内存出来。都快发版本了,我们到哪儿找这多出来的2M?

  最后,我们很屈辱地放出了一个本可以支持4v4,但阴差阳错变成只支持3v3的版本,而且PS2的游戏,你也没有机会出Patch来弥补。

  可得结论:程序员靠不住

  概率

  开篇说的Gamesutra上的Dirty Coding Tricks,里面有一篇特别神。

  他们有一次准备发布版本了,临发前手贱,加了一个文本文件打包,结果就一直在游戏加载时 Crash。查了一下,发现资源管理里面的文件标识符冲突了,新改的文本文件和另一个文件标识符一样了。神奇的地方在于,那个标识符是64位的,前32位是文件名和相对路径的CRC32,后32位是整个文件内容的CRC32,这都能冲突...修改方法很简单,打开文本文件,加一个空格,存盘退出。

  我看后深受启发,得出结论是,概率也靠不住。

  总结

  综上所述,我们顺利得出了结论,什么都靠不住。

  但那也不意味着面对bug,程序员就手足无措。为了要修复bug,我们需要的,并不是爱和正义,而是你,最勤劳勇敢的程序员。对于Debug,我们有这样一些看法:

  • 不要怀疑工具、SDK和OS,先怀疑自己的代码有没有问题。以前做PS1游戏的时候,Sony的编译器经常会编译错代码,搞得我们开发人员都迷信了,碰到诡异问题无法解释就归于迷信活动,烧个香再rebuild一下...可是这些年来这类情况越来越少,99.999的情况下那些奇怪的bug都事出有因。承认这一点,并耐心的去看这个bug,而不是到处乱改乱试,能省下好多时间。
  • 善用工具 Vtune, Perfhud等等等等工具都能给你很大帮助。前面说的那个多线程降速Bug,如果有目前常用的Windows Performance Toolkit,加上GPUView,应该是秒杀的级别。很多时候问题不好解决,是没有好的工具。
  • 在游戏里多留Debug辅助代码和profile代码
  • 日志是你的好朋友,太多bug无法直接断下程序来重现,等重现了往往现场又没了,只有日志才能帮助你追踪bug。
  • 多线程是魔鬼,我遇到过最难查的bug有80%和多线程有关,不要低估多线程程序的调试难度。
  • 易重现是Debug的第一步,很多bug之所以难查,是因为重现条件苛刻,可能是非常随机,可能是要玩非常久才能重现。如果一个bug重现概率是25%,那修复它的难度比重现概率是100%的bug不是难4倍。对于100%重现bug,为了验证一个想法,你只需要尝试1次;可对于25%重现概率的bug,你尝试4次是远远不够的,万一这4次都没重现呢?你并不知道是你的改动生效了,还是根本这几次就没重现,所以你必须试上10多次,保证那25%的情况被触发到了。如果可能,尽量试图简化bug重现条件。这是第一步,也往往是最重要的一步。
  • bug产生的地方和爆发地方越近越容易调试,因为现场都容易看见。很多AI行为难调试,就是出问题的地方离实际能看见的bug差很远,时间无法回溯,现场已然消失。所以不要吝啬assert,一个成功的Crash在现场会让你省很多力。注意积累,多思考多总结。比如像我这篇文章,记下来,分享之。一点点运气 运气是必需的,运气也是实力的一部分,而且运气会光临执着的程序员。
  • 多人协同工作可以帮助你。叫几个同事一起看,很多思路都是交谈的时候整理出来的,哪怕你只是给别人复述一下某些代码的逻辑都有可能让你豁然开朗。
  • 了解汇编,底层,执行Script的虚拟机 对于一个难重现的bug,一个Crash现场很难得,往往是自己或是测试同事数小时到一天的努力成果。对于这里难重现的bug,每一个现场都要珍惜,很多信息往往不容易找到,特别是Crash在Script虚拟机里或者在高度优化过的Release版本里面。平时要注意多积累底层的知识,这样才能在每一次Crash后充分利用不完整的现场,不浪费重现bug的工作量。
  • 保持良好心态 Debug是一件很艰苦的事情,尤其当你几天都找不到线索的时候。以前Leader讲过,他觉得Debug很有意思,因为每个Bug都是一个谜题,都有原因,把它看成是一个挑战。追查一个问题多日,沉浸其中,终于有一天找到原因,由此而得到巨大成就感,这不就是吸引我们做程序员的一大原因?

  我始终觉得,一个程序员Debug能力和优化能力的高低,很能体现他的水平,越强的程序员,越能在不可能处柳暗花明。Debug时那些灵光一闪的顿悟,需要长期浸淫在问题中,需要广博的知识面,需要充分的想象力,长期调试疑难bug后,你会发现你对系统底层,对效率,对其他模块,都会有更深入的了解。

  希望大家都能在debug中有所收获。

  相关阅读那些年,我在游戏开发中改过的bug:靠不住的OS和SDK

             那些年,我在游戏开发中改过的bug:坑爹的Vista与中间件


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2024-12-22 00:54

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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