程序猿,你调试过的最难 Bug 是?

调试 Bug 是每个程序员工作中必须品。在 Quora 上有一个和 Bug 相关的热门问答帖:《What’s the hardest bug you’ve debugged? | 你调试过的最难 Bug 是?》在众多回复中,Dave Baggett 的经历最让人惊叹,得到了 5500 多个顶。

回想起这个 bug,仍然让我有些痛苦。作为一个程序员,在发现bug时,你学会了首先在自己代码中找问题,或许在测试一万次之后,你会把问题归咎于编译器。只有在这所有的都不起作用之后,你才会把问题归咎于硬件。

这是我遭遇一个硬件bug的故事。

抛开别的不说,我曾为《Crash Bandicoot》写存储卡(读写)代码。对于一个自大的游戏程序员,这就像是在公园里散步一样轻松愉快,我认为只要几天就写完了,最终调试用了六个礼拜。在此期间我做一些其他的事情,但我一直回来处理这个bug——几天内每天几个小时。这个bug实在烦人。

这个bug的症状是,当你需要保存你的进度时,代码会访问存储卡,而大部分情况下没有什么问题…但是偶尔读写会超时…没有任何明显的原因。一个短小的写入经常毁掉存储卡。玩家要保存进度,我们不仅不保存,还擦除他们存储卡上的全部东西。天哪。

过了一段时间,我们在Sony的制作人Connie Booth慌了。我们显然不能带着这个bug发布游戏,而六个星期之后我对于问题出在哪一点线索都没有。通过Connie我们向其他 PS1 开发者求助:有没有人出现过像我们这样的情况?没有。绝对没有任何人在存储卡系统上出现任何问题。

在你绞尽脑汁之后,你能做的唯一一个调试方法就是分而治之:一点点去除程序中的代码,直到留下的代码很少但你仍然出问题。像木雕一样去除没有问题的代码,留下的就是你的bug所在。

在这样的背景下挑战在于,视频游戏是很难去除某一部分的。在你删除模拟重力或者显示字符的代码后,如何运行游戏?

你必须做的是用一个假装做真正的事情,但实际上只是做很简单的不会出现bug事情的东西来替换掉整个模块。你必须写新的支撑代码来让这些玩意正常工作。这是一个缓慢而痛苦的过程。

长话短说:我做完了。我移除了大片大片的代码,相当多,只留下了初始化代码——就是准备游戏运行系统,初始化底层硬件等等。当然,我不能显示加载/保存菜单,因为我截除了所有的图像代码。但是我能够假装用户使用(不可见的)加载/保存屏幕并且请求保存,然后写入卡中。

我最终以一个带有这个bug的很少量的代码结束——但问题仍然随机出现!在大多数情况下没啥问题,但是偶尔会失效。基本上所有的Crash的实际代码都被移除了,但还是这样。这实在是莫名其妙:留下来的代码基本上都没做什么事。

在那时——估计是凌晨3点——一个想法蹦了出来。读写(I/O)涉及精确定时。无论是硬盘、存储卡、蓝牙发送器——随便啥——做读写的底层代码都是根据时钟来的。

时钟让不直接连接到CPU的硬件设备和cpu运行的代码同步。时钟决定了波特率——数据从一头传到另一头的速率。如果计时有什么问题,硬件或者软件或者两者都会乱七八糟的。这真的,真的很糟糕,并且通常导致数据损坏。

如果我们的初始化代码以某种方式弄乱了计时会怎么样?我又看了一遍测试程序中和计时有关的代码,并注意到我们将PS1上的可编程计时器设置到了1kHz(1000跳每秒)。这是比较快了,当PS1启动的时候,默认状态大概是100Hz。因此,大多数游戏将他们的计时器设置为100Hz。

这个游戏的带头(和除我外的唯一)开发者Andy,将计时器设置为1kHz,使得Crash的动作计算更加准确。Andy喜欢矫枉过正,如果我们要模拟重力,我们应该尽可能的提高精度!

然而如果提高计时器频率莫名其妙的干扰了整个程序的计时,故而将这个计时器设置到存储卡的波特率上会怎样呢?

我将计时器代码注释掉。然后我就无法复原这个bug了。但是这并不表示bug被修复了,这个问题是随机发生的。万一我只是运气好呢?

几天过去了,我还是在玩我的测试程序。Bug没有再出现。我回到全部的Crash代码中,修改了加载/保存代码,在访问存储卡之前将可编程计时器重置为默认设置(100Hz),之后设置回1kHz。从此之后没有发现问题再次出现。

但是…为什么?

我重新回到测试程序上,试着检测当计时器设置为1kHz时出现的那些错误的模式。终于,我注意到这些错误出现在使用PS1手柄的人身上。因为我自己很少这样做,所以我没有注意到(为啥我要在测试加载/保存代码的时候用手柄)。但是有一天我们的美工等我去完成测试(我确定那时候我在爆粗口),而他紧张的摆弄着手柄。卡损坏了。“等下,怎么回事?喂,再来一次!”

一旦我发现了这两件事是联系着的,就很容易重现bug:开始写入存储卡,动一下手柄,存储卡损坏。在我看来完全是硬件bug。

我去找Connie告诉他我的发现。她转述给设计过PS1的硬件工程师。她被告知:“不可能,这不可能是硬件问题。”我跟她说问一下我能不能直接和他说。

那个工程师给我打电话了,他用着他的烂英语,我用着我更烂的日语,我们争论一会。我最后说:“我给你一个30行的测试程序,让你在动手柄的时候能够出现这问题。”他答应了。他向我保证,这是浪费时间,而他正在一个新项目上很忙,但因为我们是Sony很重要的开发者,他会试的。

第二天晚上(我们在洛杉矶,而他在东京,所以对于我来说是晚上而他是到了第二天),他给我打电话,不好意思的向我道歉。这是个硬件问题。

我还是没有完全搞清楚问题到底在哪,但是我的印象中,从Sony总部的反馈听到的是,如果将可编程计时器设置到足够高的时钟频率,会影响到主板上时钟晶振附近的一些东西。这些东西之一就是存储卡的波特率控制器,同时也设置手柄的波特率。我不是搞硬件的,所以对于细节我相当模糊。

但是主旨是主板上两个独立部分的串扰,以及手柄接口和存储卡接口数据发送的结合在1kHz的时钟频率下会导致丢位,从而数据丢失,以致卡损坏。

这是我全部编程生涯中,唯一一次因为量子力学 debug 的问题。

好了,看完了 Dave 的经历,轮到大家来说。

推荐阅读

程序员未来发展三大方向

20年资深程序员编程经验分享

解析程序员的几个成长阶段

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-03 02:09:02

程序猿,你调试过的最难 Bug 是?的相关文章

50个程序猿笑话

1.程序猿最烦两件事,第一件事是别人要他给自己的代码写文档,第二件呢?是别人的程序没有留下文档.2.程序猿的读书历程:x语言入门->x语言应用实践->x语言高阶编程->x语言的科学与艺术->编程之美->编程之道->编程之禅->颈椎病康复指南.3.还没上大学的时候,高三暑假,跑到家那边的图书城想买传说中的C++的书,然后看到一本C#,我一看,嘿,这个++还写得挺艺术的,重叠起来了,于是把C#买了回来--4.问:程序猿最讨厌康熙的哪个儿子?答:胤禩,因为他是八阿哥(b

未来 程序猿、产品汪、市场鸡注定不如运营喵?

著名心理学家凯莉在人格认知理论中指出,其实不论事实怎样,认知才是关键,心理障碍的偏差根源是认知偏差."国内专业的IT培训扣丁学堂推荐此文. 一个最明显的体现就是,在发年终奖时,很多人都会为同属于一个部门的同事多拿了一点而愤愤不平,对于其它部门拿到多几倍的钱也没有太多的感觉. 这种现象的产生,很多程序员上源自于攀比的局限性,即大家往往会局限于圈子之内而看待事物,即便已经知道自己的这种攀比行为在精神上所付出的代价要远远超过实际物质价值的本身. 所以,如何能够跳出囹圄,找到一个更大的"圈子&

转-程序猿的一些幽默 程序猿段子大全

1.程序猿最烦两件事,第一件事是别人要他给自己的代码写文档,第二件呢?是别人的程序没有留下文档. 2.程序猿的读书历程:x 语言入门 —> x 语言应用实践 —> x 语言高阶编程 —> x 语言的科学与艺术 —> 编程之美 —> 编程之道 —> 编程之禅—> 颈椎病康复指南. 3.还没上大学的时候,高三暑假,跑到家那边的图书城想买传说中的C++的书,然后看到一本C#,我一看,嘿,这个++还写得挺艺术的,重叠起来了,于是把C#买了回来…… 4.问:程序猿最讨厌康熙

论 BUG调试与(程序猿)初学者

作为一枚程序猿,BUG调试是最基本的技能,对于初学者更是重中之重.个人而言,要想为自己的程序猿生涯更上一层楼,就得知道什么是BUG调试,而且还必须知道怎么调好BUG.那么BUG究竟是什么呢?在我之前的一篇关于BUG的论述<朋友,请待你的朋友--BUG好一点!>已经说得很清楚了.BUG作为一类寄生于程序猿体内的"昆虫",其实它并不可怕.可怕的是,当我们捕获一只BUG时却不知怎么处理它. 1.对于HTML/CSS而言,如果页面布局出现了BUG,一般而言,这类BUG的攻击力最低.

一位Erlang程序猿的自白

12.00 Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE MicrosoftInternetExplorer4 /* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority

程序猿告诉你怎么选择合适自己的APP制作软件?

近几年,APP大火,创业人士都想做个APP出来一下估值上千万,传统企业都想做个APP出来进入移动化道路.然而APP制作不是一时半会就能完成的,甚至是非常有技术含量的事情.一个完全不懂APP制作技术的人士很难做出高质量的APP.那么,市面上有许多APP制作软件可选,帮助大家快速制作APP.可是,如何选择合适自己的APP制作软件呢?这件事还是程序猿最有话语权. 首先,APP制作软件分为两种,一种是傻瓜式软件,一种是简化技术软件. 傻瓜式软件,顾名思义,就是利用固定的APP模板,套用不同的UI设计从而

资深程序猿冒死揭开软件潜规则:无法维护的代码

原始博文公布于: Roedy Green's Mindproducts (http://mindprod.com/unmain.html ). 翻译链接: 点击打开链接 2014年11月25日 03:11 怎样编写无法维护的代码 让自己稳拿铁饭碗 ;-) Roedy Green 简单介绍 永远不要(把自己遇到的问题)归因于(他人的)恶意,这恰恰说明了(你自己的)无能. -- 拿破仑 为了造福大众,在Java编程领域创造就业机会,兄弟我在此传授大师们的秘籍.这些大师写的代码极其难以维护.后继者就是

关于程序猿怎样降低程序Bug的若干建议

毫无疑问,程序猿是善于思考问题的一族. 一个程序的编写都是通过:思考.设计.编写.调试.測试以及执行这些主要的阶段. 但大部分程序猿都有一个问题就是不太愿意測试自己的代码. 他们草草的调式完毕以后就觉得工作结束,測试那是測试人员的工作. 依照理论上.假设代码存在问题.那么測试人员和终于的用户肯定能够发现这些 BUG ,而等待哪个时候再返回来查找问题究竟错在什么地方确实代价不小,其代价有: 1. 影响了程序猿自己的声誉 2. 影响了产品的质量 3. 影响了客户的信任度 4. 这个时候再 DEBUG

OSChina 周六乱弹 —— 程序猿讨媳妇大全

啦啦啦,周六啦,今天倍开心- 周末能 High 成 什么样子呢,请看周五 OSCer 都 High 成了什么样 @近卫使者:-- 这... 周末就应该去散散步,走出深圳- moli : 今天回深圳了- 逛来逛去.还是深圳干净整洁,还是湖南菜好吃,还是深圳妹子漂亮- 深圳妹纸漂亮!!!小小编暂时也是深圳妹纸了,大家懂得,嘿嘿,周末都有空哦- 单身的群体是非常庞大滴,对不对,但是你有想过你是为啥单身?是何种单身狗吗? blindcat : 单身狗这个群体可以进一步细分,如:忠诚专一但脾气暴躁导致单身