最難除錯的Bug大彙集,說多了都是淚啊!
工程師與Bug是一對相愛相殺的存在,既要在解決Bug中獲得成就感,同時也討厭自己親手種下的Bug。最近,二姨家論壇裡有網友在討論如何除錯Bug,小編今天就為大家蒐集了一些號稱“最難除錯”的Bug,看看有沒有你遇到過的?
網友Xiang Liu:
答個前段時間剛發生的,不是最難調的bug,但是確實比較虐心的。
之前用xilinx一塊比較高階的開發板驗證一個高速訊號的功能,發現有一路輸出幅度是其他的1/10,感覺很詫異,於是和師弟翻了一天手冊文件,難不成這貨還有配置幅度的功能。最後無解,用萬用表在BGA焊盤和走線上一點一點地量,過了一個小時,發現....
(Bug微距圖)
尼瑪一萬多的板子表貼SMA接頭漏焊!中間大概有0.5mm的距離,高速訊號空間耦合過去10%。
於是默默用熱風槍吹上,一切正常了。
這個bug的恐怖之處在於,高速訊號可以從斷點發射出去,然後讓人誤以為這有輸出啊,不會想到根本就是個直流的斷路,直到你用了萬用表。
網友fire wind:
從前做一個嵌入式的專案,除錯工具巨難用而且隨機掛掉,也沒有core dump,只能手工新增printf看日誌除錯bug。
有一天出現了一個bug,檢視列印日誌,修改,第二天同樣的bug又出現了,但是在不同的原始碼處。繼續新增日誌,檢視,修改,這過程重複了n次,每次出現bug的位置都不一樣。
我突然醍醐灌頂,查看了下printf的原始碼...... tnnd誰把printf函式給過載了,寫入還不做校驗,會寫到別的記憶體位置上去。就像是我拿個錘子到處敲地鼠,地鼠其實住在錘子裡......
網友藍芽彪:
這個bug雖然不算最難的 ,但是一個比較熬人的……
最近產品驗收測試階段,幾輪迭代測試都顯示部分手機藍芽都一定概率丟包……但我拿那些手機做了非常多測試 也包括和測試員的一模一樣的測試環境,一直沒重現。最後階段幾個人輪番測試這個bug ,除了我大家都測試到過,但只有我有環境抓到關鍵log………兩天兩夜終於抓到了這個bug這貨怎麼出現的呢? 就是那些個二貨手機有小概率出現藍芽發呆一秒左右,什麼也不做,但又在超時的允許範圍,協議合法………
而我們的晶片居然只有在這個情況下才會出現一包資料呢包頭標誌位錯誤。
也就是一個手機的小概率隨機錯誤會誘發我們的bug。
這不是關鍵,最最關鍵的是這個bug至今還躲著我,它已經面對了所有其他人員……
另外一個bug 用頻譜儀抓晶振輻射 ,我火速叫來了我們的射頻工程師:你看這個輻射怎麼變成了對稱的雙乳峰?不應該是正態的單峰嗎? 我們一起測量了很久……後來,他不小心被電到,才悠悠地說道:你這裡沒接地?怎麼感覺有110V左右的交流電?
尼瑪,萬用表一量,真是110V ,第一次知道原來有些工程師人體可以做萬用表……
網友陳知華:
實驗室的妹子給我發訊息:你的裝置在群脈衝時怎麼感覺顯示有點跳啊(不頻繁,偶爾有一兩下)。
我去看,實驗過程中像在有人按按鍵一樣,顯示自動在翻屏。當時第一反應是按鍵部分受到干擾了,把按鍵上的電容由0.1uF改成了0.33uF。現象倒是沒是沒有重現了。但怎覺哪不對。
第二天,實驗室妹子又給我發訊息:快過來,你的裝置打靜電時隨機出現復位。一個週期內有時復位,有時又沒事!
復位!還隨機復位!!我趕過去看了現象,認為是復位電路受到干擾。
加電容,改電阻。無效!
把復位斷開,無效!!
開啟PCB檔案,改電源線路,無效!!!
就這樣兩天過去了,沒招了。說好的下週送檢樣機去現場聯調呢,吃不下,睡不好。
專案負責人(副總工)落井下石,群發郵件召開會議,會上對我一陣批鬥,說我硬體不行,並通知沒法送檢,原因是硬體有問題(實際原因是他家忙著搞裝修,軟體根本趕不出來,軟體測試報告顯示有73處bug,外加七項功能缺失),需要調整到一個月後。
我肯定不服氣呀,但又沒辦法,只好仔細檢視原理圖,現在懷疑物件只剩下了下電檢測(當電壓下降到一定值,裝置進入低功耗模式)。我把下電檢測的器件拆除,把MCU的IO上拉到電源。再去實驗,結果合格!!!於是對下電檢測進行整改,發現問題依然解決不了。
腦抽想到群脈衝時顯示亂跳,就像按鍵有人在按一樣,便懷疑到軟體沒有作延時或防抖處理。
TMD軟體工程師(專案負責人)居然不給我看程式碼,說軟體不關我屁事。讓我做好自己的事。這讓我怎麼查!!
鬧僵了,專案負責人打報告到常務總監,說我有問題不去查,還要干涉他的工作。我當時內心一萬頭草泥馬。
只好請來了總工與研發經理,說明了情況,總工說那就看看程式碼吧,和專案負責人溝通完,於是我們仨擠在電腦前一看源程式,瞬間奔潰。
按鍵檢測沒有防抖處理!
上電檢測沒有延時!
下電檢查沒有延時!
當場讓專案負責人加了相應程式碼後,再做實驗全部通過。樑子算是結下了!
網友Malasuth:
所謂難的bug/issue,往往是因為某些因素讓你無從下手。下面我想講3個有趣的issue來聊聊(本人在某半導體公司某顯示卡驅動部門做研發):
Issue 1:
國外某銀行大客戶在ATM機上用了答主公司n年前一款顯示卡,數量大約以千計。客戶報告說在開機、重啟或者其他一些條件下有千分之x的概率發生BSOD。bug本來assign給一個新人,新人搞不定找我幫忙。該bug的麻煩之處在於:
1. 不可能讓客戶寄一臺ATM機給你,也不可能讓你飛過去人銀行裡現場debug = =,只能靠dump file分析。
2. fail rate太低,定位要儘量準確,減少客戶驗證次數。
3. Driver太老了,以至於symbol都被IT搬到磁帶上進倉庫儲存了。
過程不表,是因為某個空指標未檢查,導致在一些特殊情況下掃描顯示器狀態的時候觸發了BSOD。分析過程還好,主要新人對彙編不熟所以分析有點困難。你造嗎,光是申請讓IT把driver symbol從磁帶弄回server就花了一個多星期。
Issue 2:
Windows 7; laptop, close lid action->do nothing; 用media player播放帶保護的DVD,不管初始resolution如何,關、開一次lid,自動切換為1024*768。
隊友查了一圈,沒發現哪裡明顯不對,而且competitor家的都是好的= =, 所以肯定是自家某模組的問題。原因不明,就發現open lid的時候OS會change mode到1024*768。
然後每次這種要分析OS邏輯的問題都要找答主來幫忙了= =。
還好有symbol,分析起來也比較容易。dxgkrnl裡有個class叫做BML(如果答主沒記錯的話,年代有點遠了= =)負責Best Mode Logic,答主花了幾天時間把BML class全部reverse engineering成C++,找到了原因:驅動把兩個mode都作為preferred mode report給BML (preferred按spec有且只能有一個),然後BML就暈了。close lid/open lid之後需要挑一個resolution重新恢復,BML已暈,因此異常處理一律強制為1024*768。
告訴當時負責實現這個模組的人bug的存在以及root cause,結果人家告訴答主說這個問題他早就知道啦,本來就準備重寫相應模組,會在重寫的時候把bug一起修好blablabla。答主就呵呵了,黑名單+1,以後別來問我了。
不過答主也算自己有一份私有的BML程式碼備用。
Issue 3:
答主有時候也賤兮兮的,同事遇到有趣的問題也會主動湊上去一起分析分析,尤其是和OS行為相關。
答主同事遇到個問題,某伺服器,插了8張答主公司的顯示卡,Windows 7,開機,發現3張在device manager裡被disable了。後來發現只要插6張卡就不行,5張是好的。
可能是跨部門合作的關係,答主同事之前合作的部門偏platform,因此一直從整個系統的角度考慮問題,懷疑BIOS分配不出足夠的資源,懷疑記憶體不夠,懷疑PCI-E匯流排能力問題,等等。之前他們資訊了Microsoft,插8張顯示卡OS支援肯定沒問題,而且可以最大支援256個vidpn target(我們稱之為display head,可以簡單理解為顯示路徑的數目)。
答主知道了這個問題後,就和同事一起從軟體角度看。
(debug最直接的方法,就是back trace。不過因為Windows上的driver到頂了之後就是OS模組,沒有程式碼就砍掉一堆願意分析的人,不會分析彙編又砍掉一堆,沒有symbol再砍掉一堆,願意耐心分析下去的人其實很少。)
於是又是從驅動到OS,在OS裡分析,最後發現是Windows 7對顯示能力的最大路數支援有限制, 根本不是之前被告知的256好嗎。。。而是32 (至少截至答主分析的那個時期的最新hotfix為止)。。。如果超過就會被判斷為異常,裝置無法正常enable。而且非常ugly的一點是,這個限制是通過define定義,並且用該const在watchdog.sys裡構造了一個數組用來進行相應檢查,都沒有通過os private registry key控制的可能。那臺機器上插的顯示卡每張都有6個display head,插到第6張的時候總數正好超過32,於是從第6張顯示卡開始就不能正常enable了。
答主為了驗證分析,inline hack了watchdog裡的部分邏輯,替換上去驗證,8張卡都能enable切工作正常了。又改了driver裡report capability的部分,每張卡都少report 2個display head,也能正常工作。分析結果扔給了Microsoft,也不知道後來他們改了沒有。
有趣的bug,就是能讓你在debug過程中享受樂趣的bug。
——以上部分內容摘自知乎
最後,附上物理學大師費曼先生修bug的一個小故事,在除錯bug的路上,大家一起共勉!
我跑去看那臺收音機,試著把它修好。說實在,我對它不太瞭解,不過旅館裡有一名雜工,記不清是他還是我,發現控制音量的可變電阻器上的旋鈕鬆掉了,使得可變電阻器的轉軸沒法轉動。他跑去把什麼銼了幾下,把旋鈕固定,就把收音機修好了。
我被請去修理的下一臺收音機,連一點聲音也沒有,原因卻很簡單:它的插頭沒有插。而隨著修理任務愈趨複雜,我的手藝也愈來愈高超,花招也更多了。我在紐約買了個毫安培表,經過計算後,替它接上不同長度的細銅線,把毫安培表改裝成伏特表。它並不怎麼準確,但至少我能夠量出線路上各接點間的大約電壓值,從而曉得問題出在哪裡。
其實他們之所以會請我去修理收音機,主要是因為碰上經濟大衰退,大家都窮得要命,沒有餘錢花在修理收音機上。當他們聽說有這麼一個小孩能修收音機,收費又便宜,當然是趨之若騖。結果我經常要做些奇奇怪怪的工作,像爬上屋頂校正天線等;工作愈來愈困難,但我學的也愈來愈多了。我曾接過一件工作,是要將使用直流電的收音機改裝為用交流電的,其中最困難的是不讓它發出“嗡嗡”
的聲音,而我用的方法不大對。回想起來,那次我不應該接下那件工作的,不過那時我有點不知輕重。
我在想!我在想!
另外一次也很有意思。當時我在一家印刷廠上班,印刷廠老闆的朋友聽說我在替人修收音機,便派人來印刷廠找我。這個人看來很窮,他的車子破爛不堪,簡直是一堆廢鐵,而他們的屋子也坐落在城中最貧窮的地區。半路上我問:“你們的收音機出了什麼毛病?”
他說:“每次我扭開開關時,它都會發出一些聲音。
雖然過一陣子聲音就停止,一切正常,可是我不喜歡剛開始時的聲響。”
我跟自己說:“算了吧!如果你沒錢,就活該忍受一點點聲音!”
一路上他不停地說:“你懂收音機嗎?你怎麼可能會弄收音機?你只是個小孩子罷了!”他就這樣不停嘴地損我,而我腦袋中一直在想:“他出了什麼毛病了?只不過是一點點聲音罷咧!”
可是,等我們到他家,把收音機開啟時,我真的嚇了一跳。一點點聲音?天哪!難怪這個可憐的窮光蛋也受不了!這部收音機先是大吼大叫,不停顫動,“轟——蹦蹦蹦”地吵翻天,然後,安靜下來,運作正常。我想:“怎麼可能發生這種事?”
我開始來回踱步,不停地想、想、想,終於領悟到可能是收音機內各個真空管啟動的次序顛倒錯亂掉了——換句話說,它的擴音部分不依規矩地暖身完畢,真空管也都待命工作,但這時收音機卻還沒有給它任何訊號;又或者由於其他線路訊號回輸,甚至收音機的前段線路——我說的是跟射頻(RF, radio frequency)有關的部分——出了問題,才會發出這許多聲響。而最後當射頻線路全熱起來,真空管電壓已調適好,一切便回覆正常。
那傢伙不耐煩了,對我說:“你在幹什麼呀?我請你來修理收音機,但你只在這裡走來走去!”我說:“我在想!我在想!”然後決定:“好!把所有真空管拔下來,依相反的順序放回去。”事實上,在那個時期的收音機內,不同部分的線路上往往還是用同一型號的真空管,印象中是編號212或212A的那一種。 總之我將真空管的次序顛倒過來,再把收音機開啟。它果然靜得像只綿羊一樣,線路乖乖地熱起來,然後開始廣播節目,很完美,沒有任何雜音。
如果有人曾經這樣瞧不起你,但你立刻展現實力,通常他們的態度會來個180度的轉變, 有點補償的意味。這位仁兄便是如此。後來,他還介紹我接其他工作,不斷告訴其他人我是多偉大的天才,說:“他單靠想便把收音機修好了!”他從沒想過,一個小孩子居然有能耐靜下來想,然後就想出將收音機修好的方法。
死不服輸那年頭的收音機比較好對付,因為只要你把它拆開來之後(最大困難反而是確認該動哪一顆螺絲釘),便可看出來這是電阻,那是個電容器等等,它們甚至都貼上標籤。
假如你看到電容器上的蠟已開始滴出來,那麼它一定是太熱,大概已燒壞了;同樣,如果某個電阻上有焦碳出現,它也一定出了問題;又或者,如果你看不出什麼名堂來,你可以用伏特表測量線路上的接點,看看是否都有電壓。
基本上那些收音機結構都很簡單,線路並不複雜。真空管的柵電壓通常都是1.5或2伏特,而屏極電壓都是100到伏特不等,因此對我來說,要弄清楚那些收音機的線路,看看哪裡不對,把它們修好,並不算是多難的事。
不過有些時候還真蠻費時間的。記得有一次我花了足足一個下午,才找到罪魁禍首:一隻看來毫無異狀、實際上卻已燒斷的電阻。那次請我修收音機的剛好是母親的朋友,因此我可以從容不迫地弄,沒有人站在我背後說:“你現在在幹什麼了?”相反的,他們會跑來問我:“想不想喝點牛奶或吃塊蛋糕?”不過,我後來之所以能修好那臺收音機,是因為我毅力十足。從小,只要一開始研究某個謎題,我便停不下來,非要把它解開不可。如果當時我母親的朋友跟我說:“算了,這太費事了!”我一定大為光火,因為我非要擊敗這臺鬼收音機不可。反正這麼多工夫都花了,絕不能半途而廢,我必須堅持到底,直到找出它的問題才能罷休!