調試的第一原則

      程序難免會出現各種各樣的問題,對於一般的問題,只要藉助於調試器、日誌,很快也可以解決,對於一些特殊的情況,比方非必現問題,問題現象多變,或者出現問題所在的模塊龐大而且我們對其只是一知半解,要定位到問題往往要耗費大量的時間。

      筆者在前幾日,遇到一問題,問題現象如此:在客戶端每進行一次文件分享操作,文件的分享記錄數會變爲原來的兩倍。

      筆者在接到該問題後,覺得該問題應該很好排查,畢竟只是一個必現的問題,當排查了文件的分享接口後,發現接口的每個數據項都沒有問題,才意識到該問題並沒有那麼簡單。而後,筆者意識到可能並不是分享接口的問題,可能是流程上的問題(因爲筆者是後端開發,該問題是幫客戶端人員修改,對客戶端流程並不熟悉)。於是,筆者在後端thrift接口的分發函數中加入日誌,這樣前端每次調用後端的接口就可以獲取到一條日誌,可以清晰看到前端的控制邏輯。果不其然,對比客戶端在正常的情況,出現該問題的時候,沒有調用一個取消分享的接口,筆者甚是欣喜,以爲已經找到根因,把沒有調用取消分享的接口解決後,筆者再次測試,發現問題還是沒有解決,多次分享後,分享的記錄數還是會出現不斷遞增的情況,有時是正常的,有時會突然增加多個。筆者在前端和後端都進行了調試,使用vs的調試器在客戶端獲取取消分享接口和分享接口,兩個接口參數是正常的。筆者懷疑會不會是編碼的問題,於是乎又在後端打了接口傳的數據(十六進制數據)的日誌,但是發現也沒有問題,問題一下子就進入了死衚衕,沒有任何頭緒。

       查到這裏,筆者一直糾結是:對比正常的情況,數據沒有任何變化,爲什麼會出現不一樣的現象?在糾結中,不知不覺已經到了晚上九點多,疲勞夾雜排查不出問題苦惱愈感疲憊,於是就放棄繼續排查,把問題留到明天解決。

       到了第二天,由於前一天一直在客戶端排查無果,只能轉變方向,從後端開始排查起。於是筆者在插入分享記錄的操作中,加入日誌,發現後端確實會存在插入多條分享記錄的情況,順着這條線索,很快就排查到是客戶端在thrift接口中的文件記錄參數傳遞了多個文件,正常這裏只能是一個文件記錄;很快,筆者又排查到是原先編碼客戶端的開發人員,使用了一個全局對象的成員變量傳遞給了文件分享接口,而該成員變量的值在調用接口前沒有清除,導致每做一次操作,都會增加一個新的文件數據,所以第N次操作,就會增加N個分享記錄。而此時,由於筆者已經修改了流程上要先取消分享記錄的問題,所以問題就表現爲第N次操作,會增加N-1個記錄,再加上原先流程上的問題,每次操作會增加的記錄數就是(N-1) + 1 = N,至此問題才徹底解決。

        事後,反思該問題,一個必現的問題,爲何淪落到要處理一天多,在客戶端調試的時候,應該早可以發現是客戶端傳遞的參數文件數不正確纔對,筆者這才意識到,是筆者在調試客戶端的過程中,一直都只調試第一次操作,而第一次操作傳遞的文件個數就是1,恰好這個參數就是沒有問題的,那再看多少次參數,都還是沒能發現任何問題,而筆者自己爲什麼每次都只看第一次操作的參數呢?調試了那麼多次,怎麼沒有去看第二次操作的參數,第三次操作的參數,不就一下子解決問題了?因爲第二次,第三次操作的調試要比第一次操作的調試要麻煩,潛意識中也默認第一次和後面的調試都是一樣的,所以才犯了該錯誤。我們要做的是在對問題調試之前,就要在意識中建立對該問題的邏輯認識,才能避免自己再犯同樣的錯誤。

         比方在這個問題中,我們要清楚的意識到,該問題的現象是什麼?和什麼因素有關?一開始我們是可以知道的,第一次操作是增加一個分享記錄,第二次是兩個,第三次是三個,那麼我們要清楚的把操作次數列入到調試的範疇中,我們必須考慮操作次數對問題的影響,纔可以避免筆者在前面只調試第一次的致命錯誤,第一次操作的數據是看不出任何問題的。而對於其他的情況,比方問題出現的時間,順序等等,也都應該被列入到考察的因素。這纔是調試問題的第一原則!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章