天天看點

《Effective Debugging:軟體和系統調試的66個有效方法》——第21條:把屬于同一個類型的所有問題全都修複好

本節書摘來自華章計算機《Effective Debugging:軟體和系統調試的66個有效方法》一書中的第2章,第21節,作者[希]迪歐米迪斯·斯賓奈裡斯(Diomidis Spinellis),愛飛翔 譯,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。

在某一個地方所發生的問題,也有可能出現在其他地方。之是以會這樣,可能是因為開發者在這些地方都采用了相同的思路來程式設計,也有可能是因為使用了某個很容易遭到誤用的API,或把錯誤的代碼從一個地方複制到了其他很多地方。在許多較為成熟的開發環境或對安全要求很高的工作場合中,開發者并不會在修複了某一個問題之後就止步于此,而是會把屬于同一類型的所有問題全都解決好,以防将來再出現類似的錯誤。

例如,你發現下面這條語句的除數可能會是0,并且已經将該問題解決了:

《Effective Debugging:軟體和系統調試的66個有效方法》——第21條:把屬于同一個類型的所有問題全都修複好

那麼,接下來你還應該搜尋整個代碼,看看有沒有其他地方也把totalWeight用作除數。你可以通過IDE或Unix的grep指令(參見第22條)來搜尋:

《Effective Debugging:軟體和系統調試的66個有效方法》——第21條:把屬于同一個類型的所有問題全都修複好

做完了這一步之後,還應該考慮代碼中有沒有其他地方也會出現類似的除法問題。我們需要尋找并修複這些可能出錯的地方。借助Unix的管道機制,可以輕松地實作這種搜尋。下面這段指令,能夠在四百萬行C語言代碼裡面,把可能出現除法問題的地方找出來。

《Effective Debugging:軟體和系統調試的66個有效方法》——第21條:把屬于同一個類型的所有問題全都修複好
《Effective Debugging:軟體和系統調試的66個有效方法》——第21條:把屬于同一個類型的所有問題全都修複好

經過幾次過濾之後,可疑的代碼從5731行降為5045行,又降為2032行,最後隻剩下1923行。這個代碼量,使得我們可以在合理的時間範圍之内,将其中的代碼審視一遍。盡管過濾得并不是特别嚴謹(例如,sizeof有可能傳回0、符号常量的值有可能是0),但畢竟可以使我們知道其中有哪些代碼可能出現問題。這要比那種以工作量過大為借口而根本不去檢查除法代碼的做法好很多。

最後我們還要考慮的是:怎樣在将來的工作中避免類似的錯誤。這可能需要我們對代碼或者軟體開發流程做一些調整。例如,如果程式總是由于誤用某個API函數而出錯,那麼可以提供一個更為安全的版本,并且把原來的版本屏蔽掉。例如,在項目的全局include檔案裡面,可以寫上這麼一行代碼:

《Effective Debugging:軟體和系統調試的66個有效方法》——第21條:把屬于同一個類型的所有問題全都修複好

根據上述定義,如果有人試圖在程式裡面使用gets函數(該函數很容易發生緩沖區溢出的問題),那麼代碼就無法編譯或連結。如果程式是因為對類型錯誤的值進行處理而出錯的,那麼可以考慮進行更為嚴格的類型檢查。此外,還可以通過運用靜态分析技術或更為嚴謹的配置方案來找到許多程式錯誤(參見第51條)。

修複了某一個錯誤之後,我們還需要尋找并解決其他相似的錯誤,并設法保證将來不會再出現此類錯誤。

繼續閱讀