相信很多朋友們都有調試程序的經歷,然而很多時候調試程序是痛苦而又漫長的過程;它不僅需要細心,更需要耐心,切忌心浮氣躁。但是當找出問題並順利解決它時,又會給人無比激動的喜悅。這裡總結一下筆者在程序調試中的使用的原則,工具,以及方法。這裡需要說明的是,某些原則性的東西,各種語言都是差不多的,而涉及到具體的工具和某些具體的調試方法,這裡只涉及web開發方面的內容。
總體原則:
1.找出問題原因:
程序需要調試,是因為程序有問題。而調試的第一目標是找到原因。常見調試方法, 排除法: 當我們面對整個復雜的系統時,常常完全不知道問題出在什麼地方;這個時候可以先將與問題不相關的地方排排除,逐漸縮小調試范圍。獨立模塊法: 大部分程序都有模塊結構,將可疑模塊單獨拿出來,模擬輸入相應的操作數據,看是否出現問題。比較法:如果程序或系統是基於某個平台時,可以先看看其他基於本平台的程序或系統,找出是平台問題還是本程序問題,很多時候這種方法是用來排除不成熟平台上的隱藏問題。對比法:對於自己實現的程序,可能已經有相應的開源的模塊,可以把這些程序源碼找出來,和自己的程序進行對比,這樣不僅節省時間,還能借鑒別人的優秀之處。
2.問題定位:
問題原因的多種多樣,可能這個時候你只能知道是什麼樣的問題, 可能與什麼相關, 這個時候就需將出現的代碼段找出來。而需要做到這一步,一般開發環境為我們提供很多實用工具,借助這些工具,可以一步一步地查看程序的輸入和輸出,根據每一步的輸入輸出,定位問題。
有一部分很厲害的人,可以通過閱讀代碼,找到出現問題的地方。但是很多問題都是調試者自己因為疏忽造成的,而要通過這樣方式去查找問題,幾乎是不可能的,因為已經形成固定的思維定勢。
3.解決問題
找到問題的原因和相應代碼行,解決它很多時候是一件比較簡單的事,因為這些問題往往自己疏忽或者自己考慮不周。但是某些時候並不總是這樣的,而是由於外部環境造成的,比如你的網站訪問的人數增多,你當初沒有考慮到這些數據壓力,同時也沒有考慮到高度並發性的問題,這個時候問題解決起來是你覺得比較棘手。而要解決這樣的問題,不僅僅要專注程序, 更要從系統架構方面著手,綜合各方面的知識,進行全面的考慮。
web開發常用調試工具
俗話說:工欲善其石,必先利其器。對於程序的調試,也必須借助外部工具。這裡介紹幾種在開發web程序中常常用到的工具:
xdebug, xhprof:php性能調試工具。他們都是php的一種擴展,可以很方便的安裝和配置。這兩個工具主要是將你程序的內部運行狀況,調用函數以一種簡潔的方式告訴你。讓你對程序在什麼地方占用過多的資源,那些地方需要進行優化一目了然。 順便提一下,xdebug生成的profile文件一般借助winCacheGrid查看。
firephp, firbug: 前者主要是php的調試工具,而後者是web開發必不可少的工具, 它不僅能查看請求,還能調試js,css。
在ie下面可以使用HttpWatch。如果需要將數據做深入分析,可以使用抓包工具。
php中常使用的調試函數:error_report, var_dump, print_r, var_export
mysql,apache/nginx的常用的調試技巧:分析他們日志文件也是相當重要。在linux下查看日志文件的常用命令: cat, more, less, grep, awk, sed
常見的調試技巧和方法
下面以我調試的程序來介紹一下具體的調試方法和技巧。
例子1: 這是一個php開發的游戲引擎,主要功能提供雙發球員移動位置,狀態,傳球,技能等功能控制,整個程序通過xml文件保存結果。突然某天,有兩個用戶進行比賽,返回的xml不符合正常的結構。從返回的結果來看,球員的移動位置有些不正常,其中少了某些步驟,於是決定從游戲的AI入手查找,但是也沒有發現此處有什麼異常。最後將輸入的球員數據打印出來,然後將中間產生的數據也打印出來,結合程序的處理邏輯,發現是這兩個用戶有同一個球員,因此導致在處理的時候, 兩個人的球員出現混亂。找到原因後,就將這個以球員標識改為以球隊和球員共同決定即可。
例子2:程序剛上線, 有些熱心的朋友們喜歡對程序進行一些壓力測試。某次突然20w的請求很大的一個靜態資源,直接導致硬盤癱瘓。對於這種情況,必須查看訪問日志,才知道發生什麼事。否則人家對你攻擊了, 你還找不到原因。當然對於這樣的攻擊,直接把靜態資源放到cdn上。另外,隨著訪問用戶量的增大,系統的壓力增大, 反應逐漸變慢,我們不得不考慮:以前只需要0.000幾毫秒能處理的程序,現在需要0.幾秒。這個時候程序的並發性設計就很重要了。否則會造成數據異常的情況。
例子3:使用外部軟件出現異常:例如使用memcached的時候,如果某台沒有啟動或者不能使用了。這個時候nginx一般就會對某些使用memcache的請求返回502,是不是感覺有點無厘頭,可以考慮改寫memcahce 的php擴展了