Categories
程式開發

我經歷過的最難調試的Bug


您曾經調試過的最困難的bug是什麼?本文將介紹作者至今最困難的一次調試經歷,希望從他懷疑硬件,再到懷疑軟件到最終解決問題的過程中,能夠為讀者帶來一些啟示。

我經歷過的最難調試的Bug 1

當我採訪開發人員時,有時會問這樣一個問題:“您曾經調試過的最困難的bug是什麼?”大多數人都喜歡拋出一段特殊的缺失分號的血淚史,一個難以使用的API ,或者他們抓狂地修改舊的、無文檔的代碼經歷。以下是我對這個問題的回答。

問題

問題來自一台有多個條形碼讀取器的機器。我們已經製造了8台這樣的機器,其中一台在英國生產了幾個月,而其餘7台剛剛在中國安裝完畢,而問題就出在了中國的其中一台機器上。

我們收到一份報告說其中一台機器投入生產後不久就停止了工作。客戶說有一個他們無法解除的錯誤。這個錯誤會中止產品生產,每停機一分鐘就會造成很大的經濟損失。在任何時期,我們都不希望出現這種情況。我進行了遠程操作,發現攝像頭已經停止向PLC(可編程邏輯控制器)發送結果,導致我們的軟件用戶界面發出警報。在這台機器上,將ID40作為數字IO予以連接以直接向PLC輸出通過或失敗的信號。這表明,故障可能與軟件無關,但在這個行業摸爬滾打過幾年的我知道:硬件和PLC通常都很穩定,95%的情況下是軟件出了問題,所以我總是假設是軟件出了問題。

從字面上看,這個故障意味著PLC認為觸發了攝像頭,在它再次觸發攝像頭之前沒有收到數字IO結果,要么攝像頭沒有被PLC觸發,要么攝像頭沒有輸出通過或失敗信號,要么PLC沒有接收到通過或失敗信號。我以為這是一次偶然,但如果是這種情況,重置和恢復就可以解決,而客戶反映說,這麼做沒用。這台機器將繼續生產下一個產品,然後再次停止。在遠程觀察到這一點後,我告訴他們重新啟動這台機器。我對此沒有合理的解釋,希望這只是一次偶然(從來就沒有偶然)。幾個小時後,我又接到了電話,還是同一個問題。這一次,客戶已經禁用了導致問題的攝像頭,但是現在,第二個(託管的)攝像頭顯示出相同的錯誤。

調試第一天

就這一點,我的想法是:

  • 相同的軟件在英國已經運行了幾個月,儘管在機器上略有不同。
  • 這通常是一個攝像頭的配置問題,但如果是這種情況,問題將出現在第一個產品,而不是運行了一個小時左右之後。
  • 這發生在這台機器的所有攝像頭上,所以它不是一個硬件故障。

經過辦公室內的一番討論之後,我們指示客戶工程師啟動攝像頭。這不是讓客戶做的最簡單的事情,尤其是在生產中。這些設備沒有開關按鈕,所以必須擰開一個項圈,斷開電纜,然後重新連接,這似乎解決了問題,堅持了兩個半小時。

有一個臨時的解決方案,就是從車間中獲取一個尚未發貨的控制單元,並將其轉移到辦公室,然後我們部署它,假設它是一台出現問題的機器,連接攝像頭並侵入脈衝發生器,模擬來自產品的物理機器的數字輸入,這一切大約需要一天的時間。在這段時間裡,我們發現這個問題幾乎每兩個半小時就會重複發生一次。與此同時,部署在中國的所有其他機器都在正常運行,一天24小時沒有任何問題。

調試第二到四天

我們成功解決了這個問題,攝像頭似乎鎖定了。當脈衝發生器向它發送一個觸發時,燈是固態的,觸發燈不會亮。在這一點上,我非常確信這不是一個軟件問題。我們請求Microscan提供技術支持,但仍在辦公室進行測試。在接下來的幾天,我們發現這個問題幾乎每4.5千次觸發出現一次,這就解釋了為什麼中國客戶每兩個半小時就會重複看到這個問題。我們還發現,只有當攝像頭以一定速度觸發時,才會發生這種情況。這解釋了為什麼這個問題只出現在9台機器中的1台上。

調試第五天

辦公室裡有很多關於PLC或攝像頭的爭論。雙方都不能用任何理論來解釋,相關主管建議將攝像頭的網線從機器上斷開。我們利用Telnet在批處理開始時使用以太網連接設置攝像頭,發送攝像頭正在讀取的條形碼中尋找的匹配字符串,使用以太網連接來獲取攝像頭看到的圖像以及通過或失敗的結果,這是通過Web請求完成的,直接輸出到PLC的獨立數字IO結果。在生產環境中,沒有以太網連接不是一個可行的解決方案,因為用戶需要查看圖像,這讓軟件變得無用,因為就我們而言,這樣就不進行產品檢查了。然而,我們試了一下,效果不錯,這個攝像頭整夜都在運轉,沒再鎖定。

調試第六天

我們重複測試多次,先連接以太網,然後斷開,結果是可重現的,所以認為這肯定是一個軟件問題。第一個理論是圖像請求的每次觸發都會導致問題,因此我們修改代碼以刪除該功能並將其部署到測試機器上。但這個問題仍然存在。這時,我們被難住了。以下是我們掌握的信息:

  • 如果以太網連接在運行開始後斷開(因此允許發送匹配字符串),則攝像頭可以正常工作
  • 在大約4500個產品(誤差有100個左右)之後,保持以太網連接會導致攝像頭鎖定。

這毫無邏輯可言。在我們發送了匹配字符串,並刪除請求圖像的代碼之後,我們沒對連接做任何事情。

調試第七天

我在機器上安裝了Wireshark。我不知道為什麼會這麼做,大概只是一個猜測。我們仍然有圖像請求的刪除,所以我希望看到通過Telnet的一些攝像頭的最初設置,然後什麼也沒有。我實際上看到的是通過Telnet從攝像頭向我們發送的數據流。檢查數據很明顯,它通過我們打開的Telnet連接向我們發送匹配結果來配置攝像頭設置。

這種行為在我們能找到的任何地方都沒有記錄,當然我們也沒有刻意要求這麼做。我們甚至沒有監聽響應。

我們研究瞭如何與攝像頭通信。我們在第一次需要的時候就打開了一個TCP連接,並讓它通過應用程序更改攝像頭設置。我們對此進行了修改,以便在發送完所需信息後關閉連接,如果需要則重新打開連接。在接下來的幾天,我們對它進行了徹底測試。

結論

我還是不明白這是怎麼把攝像頭鎖定的。我們通過Telnet接收TCP結果,但是我們沒有讀取流,這是在緩衝中積累起來的嗎?這是如何導致攝像頭鎖定的?我仍然不能回答這些問題。

我們向客戶部署了新版本的軟件,在撰寫本文時,它已經運行了近一年,不需要進一步修改。從那時起,它已經生產了大約1000萬件產品。我從中學到的是負載測試的重要性。我們測試了機器,但沒有達到所需的水平。我們在辦公室運行了幾千個產品,但客戶希望在一定時間內批處理運行180k個產品,我們沒有測試過任何接近這個水平的連續操作。

從那以後,我們詢問每個客戶最大的批量處理有多少,然後我們用兩倍的量來測試。

原文鏈接:My hardest bug to debug