Item 40: Add Debugging Functionality#
透過告知程式「它正在被除錯」,你可以反過來讓程式主動協助你除錯。實現這一點需要兩樣東西:啟動 debugging mode 的機制,以及實作該模式的程式碼。
進入 Debug Mode 的方式#
- 編譯選項:例如在 C/C++ 中定義
DEBUGconstant - 命令列參數:例如 Unix
sshd的-d開關 - Signal:例如舊版 BIND domain-name server
- 隱藏按鍵組合:例如某些 Android 版本連點 7 次 build number 啟用 USB debugging
為避免意外在 production 環境啟用 debugging,最好在 debug mode 啟用時顯示醒目的提示訊息。
Debug Mode 可以做什麼#
記錄操作(Log Actions):當某些事件發生時通知你,並記錄事件序列供日後分析。
顯示更多資訊:在畫面上疊加額外資訊。例如 Minecraft 的 debug mode 會疊加顯示 FPS、記憶體使用量、CPU 負載、玩家座標等資訊。Web 應用程式可以在滑鼠懸停時顯示資料庫 ID。
啟用額外命令:透過 command-line interface、額外選單或 URL 來存取。可用來顯示和修改複雜資料結構、dump 資料到檔案、改變程式狀態等。
進入特定狀態:例如跳過精靈介面的前六步直接到第七步,或在遊戲中直接跳到高等級。
增加透明度或簡化行為:
- 讓 daemon/service 在前景執行並顯示輸出
- 減少到單一 thread 來排除非並行相關的問題
- 用簡單演算法替代複雜演算法
- 用同步 API 替代非同步 API
暴露額外介面:對於缺少 UI 的嵌入式裝置或 server,可以加入 command-line interface、serial connection,或嵌入小型 HTTP server。
模擬外部故障:模擬網路封包隨機丟棄、磁碟寫入失敗、無線電信號衰減、即時時鐘故障等。
執行罕見的 code path:透過改變程式設定來偏好執行罕見路徑。例如將 buffer 初始化為僅 1 byte,強制 reallocation 頻繁發生;或設定極小的 hash table 和 cache buffer 來壓力測試。
重點回顧#
- 為程式加入進入 debug mode 的選項
- 加入命令來操作程式狀態、記錄操作、降低執行複雜度、跳過 UI 導航、顯示複雜資料結構
- 為嵌入式裝置和 server 加入 command-line、web、serial 介面
- 用 debug mode 命令來模擬外部故障