Bug 越少,使用者評價越高;開發階段越早發現問題,上線後處理越從容。除錯不僅是用 IDE 單步執行,更是一套涵蓋程式碼撰寫、防禦性設計、記錄追蹤、例外處理的系統工程。本文從基本原則進階到實戰技巧。
回傳錯誤碼易被忽略(誰每次都檢查 GetLastError()?),且無法攜帶豐富上下文。
class MyException : public Exception {
public:
int ErrorCode;
AnsiString Context;
__fastcall MyException(const AnsiString& Msg, int Code, const AnsiString& Ctx)
: Exception(Msg), ErrorCode(Code), Context(Ctx) {}
};
// 拋出
throw new MyException("Database connection failed", 1001, "ConnectToServer()");
// 捕捉
try {
ConnectDatabase();
}
catch (MyException& E) {
LogError(E.Message, E.ErrorCode, E.Context);
ShowMessage("Error: " + E.Message);
}
catch (Exception& E) {
// 捕捉所有 VCL 例外(除 ESocketError 外)
LogError(E.Message);
}
catch (...) {
// 捕捉所有非 C++ 例外(SEH、外部 DLL 等)
LogError("Unknown exception");
}
catch (...) { throw; } 重新拋出,保留原始例外資訊__finally { Cleanup(); }(Borland 擴充)確保資源釋放,無論是否拋出例外noexcept)優化效能與表達契約服務程式、ISAPI/CGI、即時系統、客戶現場無法連接除錯器時,記錄系統是唯一可見度來源。
OutputDebugString(L"Entering ProcessOrder()\n");
DebugView (Sysinternals) 捕捉生產機輸出SendDebug、SendDebugEx、SendMethodEnter/ExitGDebug.exe 獨立運作,未安裝時自動無操作TRichEdit 記憶體碎片與效能問題TListBox 設 Style = lbOwnerDrawFixed 自繪,支援顏色/圖示| 層級 | 內容 | 範例 |
|---|---|---|
| TRACE | 函數進出、參數值 | Enter: SaveFile(path='data.bin', size=1024) |
| INFO | 關鍵里程碑 | User login: admin@corp.com |
| WARN | 可恢復異常 | Retry 3/5: Connect timeout |
| ERROR | 失敗操作、例外 | SaveFile failed: Disk full |
| FATAL | 程式即將終止 | Out of memory, terminating |
i == 999 && user.Id == 123Remote Debug Server 部署於目標機,IDE 透過 TCP 連接nullptrat())std::lock_guard、自定義包裝器)assert() / DebugCheck() 驗證前置/後置條件const、成員函數 const、變數不可變除錯藝術的核心是預防大於治療:乾淨程式碼減少 Bug 產生,例外機制讓 Bug 無法隱藏,記錄系統在無 IDE 環境提供可見度,IDE 技巧加速定位。將這些實踐內化為習慣,你將從「滅蟲工」進化為「軟體工程師」。