老司機找bug的心路歷程
一.碼畜:靠編譯器幫自己查語法錯誤
消滅筆誤:編寫適合程序員的鍵盤練習
if (常量==變量或表達式)
使用goto接力超長的if,switch
連續的if還是if elseif
多個條件的組合:精心的排版
多重括號的匹配
條件編譯
各種const:不要糾結各種常量了,這個世界上唯一不變的就是變化。用APIWriteProcessMemory還能修改正運行的其它進程的內存裏面的所謂常量呢!
查看宏展開後的.i文件:VC編譯選項加/EP /P(項目、屬性、配置屬性、C/C++、預處理器、預處理到文件:是,預處理取消顯示行號:是),重新編譯,查看宏展開後對應的.i文件。gcc加-E
偶遇到莫名其妙的編譯錯誤都是用“每次用/*...*/或#if 0...#endif註釋掉不同部分再重新編譯,直到定位到具體語法出錯的位置。”的方法解決的。
附加包含路徑、附加庫路徑、附加依賴庫的設置。
二.碼農:靠調試器幫自己查邏輯錯誤
for/while語句後多余的分號
while/do while語句在語義上的歧義
條件斷點
消息斷點
數據斷點
__asm int3或DebugBreak()斷點
在內存窗口中觀察數據的原始字節形態
Call Stack:崩潰的時候在彈出的對話框按相應按鈕進入調試,按Alt+7鍵查看Call Stack即“調用堆棧”裏面從上到下列出的對應從裏層到外層的函數調用歷史。雙擊某一行可將光標定位到此次調用的源代碼或匯編指令處,看不懂時雙擊下一行,直到能看懂為止。
“給定一個小點的輸入,完整單步跟蹤(同時按Alt+7鍵查看Call Stack裏面從上到下列出的對應從裏層到外層的函數調用歷史)一遍。”是理解遞歸函數工作原理的不二法門!
遞歸函數關註以下幾個因素
·退出條件
·參數有哪些
·返回值是什麽
·局部變量有哪些
·全局變量有哪些
·何時輸出
·會不會導致堆棧溢出
語法糖越甜,編譯調試查錯越苦!
C++的隱藏調用:單步類的實例“構造”或“復制”或“作為函數參數”或“作為函數返回值返回”或“參加各種運算”或“退出作用域”的語句對應的匯編代碼幾步後,就會來到該類的“構造函數”或“復制構造函數”或“運算符重載”或“析構函數”對應的C/C++源代碼處。
任務管理器、VMMap、Process Monitor、Process Explorer、GDI泄露檢測工具、……
三.碼人:靠寫日誌幫自己查運營錯誤
CrashDump或Core的無力。
PDB的無力。
線上Debug的無力。
觀察復雜數據的無力。
多線程調試的無力。
調試時序高度依賴代碼的無力。
調試萬年一遇非法數據的無力。
有時不將“調用函數名字+各參數值,進入函數後各參數值,中間變量值,退出函數前準備返回的值,返回函數到調用處後函數名字+各參數值+返回值”這些信息寫日誌到文件中是無論如何也發現不了問題在哪裏的,包括捕獲各種異常、寫日誌到屏幕、單步或設斷點或生成core或dmp文件、……這些方法都不行!
四.碼神:靠冥想和頓悟幫自己查不可再現錯誤
假死的各種原因:
·控制循環的變量的取值範圍有符號/無符號,==/<=
·控制循環的變量沒變
·控制循環的變量被外部程序修改
·各種資源泄露
·死鎖
·網速變慢或網絡資源耗盡或網絡時通時斷
·權限、UAC、殺毒軟件實時防護
·操作系統或軟件自動升級
·以為系統時間不可逆
·以為系統時間相關變量不會溢出(GetTickCount()約49.7天就歸0了!)
·……
不要企圖優雅的結束(因為這是不可能辦到的)
而要在爛的不能再爛的攤子上也能重整河山!
轉自 http://blog.csdn.net/zhao4zhong1/article/details/53078924 侵刪
老司機找bug的心路歷程