除錯是每個程式人在日常的開發生活中不可或缺的一環,任憑你是功力如何通天的程式設計高手,也不敢保證自己所寫下的每一行程式碼都完美無缺、無懈可擊。只要有程式碼的產出,就有可能暗藏程式臭蟲,每個程式人都必須具備除錯的能力。

之前談程式開發者的生產問題,有的程式人或許撰寫程式碼的速度快,但是所寫下的程式碼品質不佳,導致臭蟲滿天,反而額外耗費許多時間。也有的程式人拙於除錯,一旦所寫下的程式碼內含臭蟲,就得花上許多時間和心力才能找出臭蟲並且解決。這些情況都是程式開發生產力的大敵。

除錯技巧的重要性,不亞於開發技巧
講程式設計技巧的書多,講除錯技巧的書反而少。相較於除錯在程式設計領域的重要性而言,這種現象似乎有嚴重的失衡情況。大多數程式人所受到的訓練,也是如何寫下更好的程式碼,但除錯技巧的訓練,似乎只能仰賴程式人自身在實戰中的磨練、實務經驗的累積,及倚靠個人天份的領悟。

你可以試想看看,當別人或者是你自己發現你的程式有問題時,你是怎麼解決程式問題的呢?

你是否會依循一個系統性的方法,來有效地解決所面對的問題呢?或者你只是舉手無措,不知從何著手,只會胡亂地看著自己的程式碼,接著盲目試著做一些修改,然後重新執行程式,也不確定自己的修改是否修正問題?

除錯的第一步──找出重現重蟲的方法
如果你能依循一個系統性的方法,解決問題的平均效率通常就會比較高,但倘若你只是亂槍打鳥,只憑直覺和沒有根據的猜想解決問題,那麼可以想見的,運氣差一點的話,解決問題的周期自然就會長很多。

我試著介紹一個常見除錯方法。除錯的第一步,便是找出可以重新複製(Reproduce)臭蟲的方式。如果臭蟲是由專職的測試人員所找出來,那麼通常在他們的測試報告中,會提供如何引發錯誤的情境。例如,在什麼作業系統、使用瀏覽器的版本、透過怎樣的操作步驟、在每個步驟中輸入什麼輸入值,便能夠造成這個錯誤。

如果這個臭蟲並非測試人員找出,而是由你自己發現,那麼對你來說,找出如何重新複製此一錯誤的方式,也是除錯很重要的基礎。

有時很容易使臭蟲現身,但有時很難。容易現身的臭蟲可以省去不少力氣,行蹤飄忽不定的臭蟲則叫人頭痛。有些臭蟲是難找易解,但有些臭蟲則是易找難解。遇上難找難解的臭蟲,那肯定是程式人能遭遇到最艱困的局面之一。

重新複製臭蟲為什麼重要?因為重新複製臭蟲是每一回合除錯動作的開端,你要能重新複製臭蟲,才能有效啟動其他除錯的動作。

試圖簡化重現臭蟲的過程,以縮小問題的範圍
如果不能有效複製臭蟲,而只能憑著運氣,讓系統不斷地運作,等待臭蟲的出現,那麼可以想見的,要想解決臭蟲,就必須耗費更多的時間。在一個持續運作的系統裡,有些臭蟲搞不好一個月才會發生一次。

如果能夠找到重新複製臭蟲的方式,那麼可以試圖加以簡化,因為倘若這個方式十分的冗長,例如要經過十道手續才會發生(通常是來自於專職測試人員的回報),那麼對除錯工作來說,仍然會帶來困擾。如果能夠精簡化重新複製臭蟲的方式,例如找到其中關鍵的三個步驟(也就是說,即使不執行其餘的七個步驟仍然可以複製),那麼對除錯的效率來說,便會有很大的提升。

事實上,簡化重新複製的手續,也有助於縮小問題的可能範圍。因為當牽扯進來的輸入動作越多時,代表可能出錯的環節越多;當影響的因素越少,有嫌疑的環節就比較少。這對於推測可能的問題所在,會有不錯的幫助。

如何簡化呢?基本上就是逐一地抽取原先重新複製的動作,重新檢查問題是否可以重現,倘若可以,便代表這手續並非必要,便可以從中移除。

除了操作與輸入值,環境也可能是影響程式能否正常執行的因素
想要重新複製臭蟲,除了操作的方式或給定系統的輸入值之外,還有一個很重要的因素,便是執行的環境,例如作業系統、瀏覽器版本,或者是其他安裝的相關軟體的版本。

由於使用者的操作環境,往往和開發者不同,因此,十分普遍的現象,是程式在開發者的環境中運作得正常無誤,在使用者或測試者的電腦,問題卻是層出不窮。

例如,使用過微軟MFC的開發者可能都遇過,選擇以動態的方式鏈結MFC的程式庫,這在開發者的電腦上都是具備的,但是,當使用者電腦的路徑上,並沒有MFC的DLL檔案時,便會無法執行程式。又例如,在Windows XP上有個名為Windows Media Source Filter的DirectShow filter,在Windows Vista及Windows 7上卻沒有這個filter,那麼當程式假設此filter必然存在時,在Windows XP上能正常運作,但在Windows Vista及Windows 7上就會出錯。
很多程式人最愛掛在嘴邊的一句話便是「在我機器上很正常(It works on my machine!)」,但這樣的說法無濟於事,你的程式是要在每一個設定應該要能支援的環境中都能執行,不正面地面對問題,問題不會自動消失。
要意識到問題可能和環境有關,並不是每個程式人都能具備的直覺判斷。不過,這時常是導致問題的原因。倘若同樣的操作步驟,在測試者的機器上「屢試必爽」,在你的機器上卻是「屢試不靈」時,那麼和環境的關聯性自然就大了。你必須讓自己習慣性地往這個方向猜想才行。

常見的環境因素,除了上述的作業系統、瀏覽器、媒體撥放器版本……等,還有像是JDK版本、.NET執行時期環境的版本、資料庫版本,都有可能會影響到程式執行的正確與否。

沒有經驗的程式人,只能逐一地嘗試安裝與測試著一樣版本的軟體,然後再依據同樣的流程來複製重蟲。不過,在固定領域有過足夠經驗的程式人,通常都已經踩中過地雷了,所以能夠更快地判斷出可能造成問題的環境組態。例如Windows Vista因為有所謂UAC(User Account Control),有些涉及到必須擁有管理者權限的動作,都有可能造成在Windows Vista上引發錯誤。有過經驗的程式設計者,很容易可以猜測出有問題的組態。

若不能簡化臭蟲重現過程,有嫌疑的程式碼範圍就會很大
總的來說,重新複製臭蟲的出現,是有效率地除錯的第一步。

這個動作牽扯到你必須找到重製的操作步驟、輸入值、還有環境。不論是操作步驟或環境,最好都能夠找到最關鍵、與問題直接有關聯的步驟及環境組態。因為步驟越少、需要控制的環境組態越少,越能夠加快除錯的動作。

另一方面,因為重新複製臭蟲的步驟和環境,都有可能為我們指出真正問題的所在,因此,當步驟一多、涉及的環境組態一多,那麼有嫌疑的程式碼範圍就越大,在接下來的除錯過程中,也會製造出太多無謂的煙霧出來。

專欄作者

熱門新聞

Advertisement