zoukankan      html  css  js  c++  java
  • 最难忘的Bug调试经历

    摘要:目前,著名的社区问答网站Quora上出现一个很火的讨论:你调试过最难的Bug是什么?大家纷纷留言,把自己最痛苦的一次调试经验写下来。

    相信每位程序员都有过一段不堪回首地Bug调试经历,程序员一听到自己的程序有Bug,会有各种搞笑的反应,大家可以移步去看看“ 程序员遇到Bug后的30种常见反应 ”。

    目前,著名的社区问答网站Quora上出现一个很火的讨论: What's the hardest bug you've debugged?很多程序员在下面留言,把自己最痛苦或者最难忘的Bug调试经历分享给大家,笔者就所讨论的内容,整理了两位程序员的回答。不知大家是否有过同样的经历。

    Dave Baggett:代码、硬件 谁之过?

    ITA Software联合创始人、inky.com网站创始人Dave Baggett分享了自己痛苦的调试经历,在苦苦反复测试代码后,竟然发现是硬件惹的祸。

    我为Crash Bandicoot写了内存卡(加载/保存)代码,我花了6周时间才停止对这段代码进行调试,在这段时间里我还做了些其它东西,但还是会过来调试这个Bug——可能是几个小时、几天。

    在每次保存进程的时候,程序就会一直访问内存卡,并且进行正常工作。仅仅一个短暂的写入操作,常常会破坏内存卡。玩家会保存一些东西,而它不但不会去保存,反而还会去破坏内存卡。

    显然,我们不能跳过这个Bug,即使6周后,我仍然也没发现任何线索。后来,我们通过Connie把内容放到了PS1开发者论坛上,看是否有人遇到过类似问题?答案是否定的。

    当程序员无计可施的时候,唯一能做的是对代码进行分而治之,不断地去排查错误,消灭错误,直到最后剩下非常小的一块,再去慢慢研究问题所在,可不幸往往就这样,在排除了许多错误以后,该Bug还是会出现。

    在这个过程中,我们所面临的挑战是如果把代码删除了,该如何让游戏继续运行下去?我们需要替换整个模块,并且模拟一些真实的东西,但实际上,这并未起到太大作用。你必须要编写新的架构代码来保持整个游戏的运行,这是慢且痛苦的过程。

    我不停的移除越来越多的代码,直到只剩下启动代码——仅仅是启动这个系统并且初始化渲染硬件等。当然,这是肯定不会提供加载/保存菜单,因为我已经移除了所有的图形代码。不过我可以假设用户在使用(不可见)加载/保存操作,并且询问是否保存,最后再写入卡上。

    最后,只剩下极少的代码在工作,但Bug仍然存在,大多数时候都可以正常工作,但每隔一段时间,它就会失败。几乎所有的Crash代码都被移除了,但仍然发生错误,太莫名其妙了,剩下的代码真的没有做任何事情。

    此时,大概上午3点左右,一个念头在脑海一闪而过。读和写(I/O)操作需要精确定时。无论你是否在处理一个硬盘、闪存卡、蓝牙发射机——不管怎样,底层代码的读写操作必须要根据精确的时间点来执行。

    时钟周期让硬件设备可以不直接连接到CPU——并且让代码运行与CPU保持同步。时钟决定Baud Rate——数据从一端发送到另一端的速率。如果时间混乱了,那么硬件或软件都有可能会有问题,这真的是太糟糕了,而且在通常情况下,还会导致数据损坏。

    倘若我们编写的设置时间的代码混乱了,那么定时会发生怎样的情形呢?我再次查看了与时间相关的测试代码,注意到设置的可编程时间定时是PS1到1kHz(1000ticks/second),这是相当快速的,大多数游戏一般都是设置在100Hz这样。

    随着时间的推移,我不停地测试程序,回到Crash代码块,并且修改加载/保存代码,在访问内存卡之前,把可编程时间定时调整到默认设置(100Hz),然后再将其调制1kHz,我们再也没看到读/写问题。

    为什么,我反复地思考和测试,并且不停地调整时间。有一天,我突然细微地观察到了两个东西,并且很容易重现:开始写内存卡、操纵控制器、存储卡损坏。这看起来就是个硬件Bug。

    后来,我找到曾经设计过PS1的硬件工程师Connie,并且把发现的问题告诉她,她回答:“不可能”,并且我们进行了争论,我想当场测试给她看,但是她觉得是在浪费时间,并且她为新项目忙地焦头烂额。第二天,她向我道歉,并且告诉我,的确是一个硬件Bug。

     

    图片来源:《程序员杂志》

    Amir Memon:难以重现的Bug

    Amir Memon是一名iOS软件工程师,他分享了一个有关Bug难以重现的调试经历。

    几年前,微软和Mozilla曾报道过Flash Player会出现崩溃的现象,然后我们却无法重现这个崩溃,我们想从日志中知道在哪里崩溃,但毫无意义。后来,我们才知道,出于同样的错误,有几个崩溃记录指向了不同的代码行。

    最后,我们团队里的一个很棒的质量工程师追捕到了这个崩溃所在,并且能够相当可靠地重现崩溃步骤,事实证明,只有在使用慢的硬盘驱动时才会发生。

    该崩溃只会发生在一个视频被销毁后,Flash播放器破坏序列(比如在某些情况下,当你导航到另一个页面的时候)。视频文件流没有得到及时清除,随之线程同步问题暴露出来。

    之所以会提这个Bug,主要是因为它很难在一个系统内部重现,事实上,在程序崩溃的地方存在不少的多线程问题。最后,我修复了这个问题,并且很受欢迎。它阻止了成千上百万个崩溃的发生。

    各位程序员,你们遇到过最难忘/有趣的一次调试经历是什么?或者你认为最难的一次调试Bug是什么呢?不妨分享一下哦。

    来自:Quora

  • 相关阅读:
    《破茧成蝶》读书笔记——价值
    《破茧成蝶》读书笔记——技能(2)
    《破茧成蝶》读书笔记——技能(1)
    《破茧成蝶》读书笔记——信念
    《HeadFirst:HTML & CSS(第二版)》——开篇废话
    图片旋转方法
    uploadify 3.0 详细使用说明
    提高mysql千万级大数据SQL查询优化30条经验(Mysql索引优化注意)
    Sql 中 不等于'<>'与 NULL
    c#中获取存储过程的返回值(return Value)
  • 原文地址:https://www.cnblogs.com/code-style/p/3412396.html
Copyright © 2011-2022 走看看