跟遺留程式碼打交道:幹掉頑固漏洞的簡單方式

edithfang發表於2014-09-18



跟遺留程式碼打交道會是比較困難的,尤其是如果程式碼是由某位不知道名字的程式設計師用一種不熟悉的語言編寫的話。但跟據Mob Programming 的R Jason Kerney 和Llewellyn Falco的說法,遺留應用中的bug是可以相對迅速地發現和修補好的,這個過程只需要若干相當直截了當的技巧。

“我通常是沒有機會去理解(遺留)程式碼的,所以我必須想出辦法在不理解的情況下繼續工作,”Falco說。

在奧蘭多舉行的Agile2014的一場研討會上,Falco和Kerney展示了他們在不需要過多的研究遺留程式碼的情況下尋找和修補漏洞的能力。該研討會的主題是遺留程式碼處置,兩位程式設計師把有效地跟遺留程式碼打交道比作切芒果。芒果肉就是重要程式碼。其餘的則是皮或者核。他們給自己的技術起了個通俗的叫法:“去皮切塊”。

去皮切塊法的原理是縮小焦點直至待檢查的程式碼是與特定漏洞直接相關的。Falco解釋瞭如何從外部開始層層剝離直至重要的程式碼。Kerney展示瞭如何在存疑的程式碼中切塊。這樣的話,很容易就可以看到哪裡出了問題,知道如何去修復。

用例

他們使用了一個假設的金融應用來進行演示,該應用會在給現有記錄追加資訊時時產生多項新記錄。大致是如果“Joe”有3筆獨立的貸款,遺留程式碼就會為他生成3條獨立的記錄,每一筆貸款一條。應用應該已經給Joe原來的那條記錄追加了貸款。

討論的遺留應用假設是由捷克的外包軟體團隊編寫的,現在這支團隊已經不復存在,因此沒人可以對程式碼做出解釋。在這種設想的情況下,是沒有辦法可以輕鬆訪問資料庫本身的,因此也沒辦法通過庫去了解。

難以破譯的遺留程式碼樣例

唯一知道的變數是程式碼執行時預期應該做什麼事情,以及程式碼的實際執行情況。Falco和Kerney說,僅利用這一點資訊,他們就可以確定遺留程式碼的問題出在哪裡並修復問題。

程式碼分離

剝除程式碼技術要求把硬程式碼和重要程式碼分離。基本計劃是把一個複雜的方法分成兩部分。第一部分包含的是硬程式碼,第二部分包含的是我們希望理解的程式碼。然後把重要程式碼析取出來作為第二個方法,與其他程式碼區隔對待。

一般而言,這會需要對“程式碼的推拿”進行一些簡單的重構,讓執行順序變得更加可行。Kerney和Falco強調,這一重構仍然是非常簡單的,足以在無需理解待測遺留應用的遺留程式碼庫的情況下就能完成。

逐塊分割

往往會有部分程式碼不好打交道,沒辦法像上面那樣進行分離。這些就是Falco-Kerney芒果方法論中的坑。這裡就要採取切割術了,即把有問題的元件模擬出來。

Kerney使用了一種叫做EasyMock的工具來把資料庫模擬出來,然後把它從不相干的東西中抽象出來。他指出這與測試驅動開發的模擬過程非常類似。區別只是前者不去檢查新程式碼是否通過測試,而是測試現有程式碼中那一部分沒有通過測試。

打補丁

通過首先剝除問題範圍以外的程式碼,然後將問題範圍內不相干的程式碼切除,Falco 和Kerney最後得到的幾行程式碼可能就是問題所在。由於只需要聚焦於幾行程式碼,兩人就可以更好的確定什麼地方出了問題。

在本例中,最後的結果表明,有兩行程式碼寫錯了次序。通常情況下這兩行程式碼的次序是沒有影響的。這裡出了問題是因為Java語言及其運作方式的錯綜複雜。

Falco和Kerney對簡化後的程式碼執行測試時,顯然是第一行程式碼被呼叫得太快了。找到正確的順序、修訂漏洞並反敗為勝並沒有花費太多的時間—這一切都不需要理解程式碼。

一點告誡

重要的是要注意到這些技術並不能保證新的依賴性錯誤不會發生,如果外部程式碼引用了被修改的程式碼的話。然而,正如Kerney所指出那樣:“理解程式碼並不能確保在其身上不會出現任何連綿不絕的依賴性。”

至於在舊的遺留應用上尋找和修補漏洞,有人會提出說找出遺留程式碼的工作方式純屬浪費時間。不花時間學寫程式碼的話可能會喪失掉一些(也許是可觀的)學習的機會。然而,如果這種學習如果真的值得開發者花時間的話,他或她可以在漏洞解決之後再去學習程式碼。

看看工具

Falco和Kerney利用了面向Java的軟體工具進行演示。他們使用的基礎工具是Eclipse IDE、JUnit測試工具、覆蓋測試用的是EclEmma,模擬物件則使用EasyMock來生成。究竟用什麼工具要視具體的專案而言。

後續步驟

Llewellyn Falco針對.Net開發者解釋這些過程的系列視訊可以在YouTube上面找到。

你可能不想將遺留應用遷移到雲上,但在雲端進行開發和測試仍然有一些好處。

當你把遺留程式碼的所有漏洞都補上時別忘了跟蹤新專案的缺陷。
相關閱讀
評論(2)

相關文章