2009年3月10日星期二

草率易出错,编码需谨慎

今天等SVN上的版本管理方法稳定下来以后,我开始提交这更新后的driver。

因为改动很多,所以我针对Debug/Release版本都仔细测试了一下,登录进入游戏,看上去很好,没有什么问题,于是放心提交了。

晚上突然出了点意外,有一两个玩家运行客户端以后卡在一开始的启动界面就不动了 - 这个发出去的客户端是上周五晚上build的,尚没有包含我更新后的driver。一个同事检查了半天,最终确认OGRE、CEGUI均无问题,一直到driver启动也没有意外。

于是我在本地build了一个版本,传给对方,没想到一过去就崩溃了。很纳闷,回来看了看,发现版本组织有点变化,原本build出来的平台lib & dll会自动拷贝到发布目录下,现在居然没有这一步了。一问,需要手工拷贝 !@(#*!&@#*(!@ 也就是说,我今天提交的driver其实根本没有经过测试,只是编译通过了而已,生成的dll没有放到发布的目录,所以没有被使用。对工程做出这样的变化没有周知真是添乱啊!

好一番折腾,排除了几个driver的bug以后总算build出来了稳定的客户端。发给对方,没有改善,但是我发现启动以后即使什么都不做,机器的CPU占用率也特别高。回到我本机一试验,果然,一启动就是50%,同时加载脚本的话就到了100%,而我是双核的机器,说明一开始就耗尽了一个核的资源。既然在本地能够重现,问题就好办了。

诊断的结果让我有些无语,原来是启动界面处理消息在PeekMessage以后没有Sleep。最早的代码当然有,但是上周合并版本时,程序员遇到了一些问题,点击退出无效,于是对代码进行了一些调整。显然,他们没有找到真正的原因,只是草率在收到点击退出时调用exit(),进行了很不优雅的退出;另外,他们还随意修改了一处和退出无关的代码,导致CPU占用一个核的100%。而外网那些只有一个核的玩家因此就倒了霉,启动时大部分时间都用来做死循环了。

所以说,处理问题不可草率,要想清楚原因,做出合理的解释,才能针对性的设计解决方案。倘若到处对可疑代码打补丁,那不是排除问题,而是埋地雷。

ps. 既然单独开了一个线程取消息,为什么不用GetMessage而是PeekMessage?想法真诡秘啊!

没有评论:

发表评论