// 標頭檔 CommonDebug.h
#pragma once
#ifdef _DEBUG
#define MY_TRACE(fmt, ...) printf("[TRACE %s:%d] " fmt "\n", __FILE__, __LINE__, __VA_ARGS__)
#define MY_ASSERT(expr) do { if(!(expr)) { printf("[ASSERT %s:%d] %s\n", __FILE__, __LINE__, #expr); __debugbreak(); } } while(0)
#else
#define MY_TRACE(fmt, ...) ((void)0)
#define MY_ASSERT(expr) ((void)0)
#endif
bool g_debugEnabled = false;
void ParseDebugFlags(int argc, char* argv[]) {
for (int i = 1; i < argc; ++i) {
if (strcmp(argv[i], "--debug=on") == 0) g_debugEnabled = true;
else if (strncmp(argv[i], "--debug-level=", 14) == 0) g_debugLevel = atoi(argv[i] + 14);
}
// 亦可讀環境變數 getenv("MYAPP_DEBUG") 或 JSON 配置
}
優點:生產環境無需重編譯即可開啟詳細日誌/資料結構傾印/效能計數器。
#define STRINGIFY(x) #x
#define LOG_VAR(x) std::cerr << "[" << __func__ << ":" << __LINE__ << "] " << STRINGIFY(x) << " = " << (x) << std::endl
// 用法
int timeout = 30;
LOG_VAR(timeout); // 輸出: [MyFunc:42] timeout = 30
// 進階:結構化日誌 (JSON)
#define LOG_VAR_JSON(x) LogJson({{"func", __func__}, {"line", __LINE__}, {"var", STRINGIFY(x)}, {"value", (x)}})
#include
void Process(int* ptr, size_t len) {
assert(ptr != nullptr); // 前置條件:指標非空
assert(len > 0); // 前置條件:長度合法
// ...
assert(result >= 0); // 後置條件/不變式
}
#include
#include // span, not_null, owner
void Transfer(gsl::not_null from, gsl::not_null to, Money amount) {
Expects(from->Balance() >= amount); // 前置條件:編碼期文檔 + 運行期檢查 + 靜態分析提示
Expects(from != to);
from->Withdraw(amount);
to->Deposit(amount);
Ensures(from->Balance() == old_balance - amount); // 需手工保存舊值
Ensures(to->Balance() == old_balance + amount);
}
GSL 優勢:
| 場景 | 技巧/工具 | 關鍵命令/代碼 |
|---|---|---|
| 記憶體洩漏 | CRT 洩漏檢測 | `_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);` 程式結束自動報告 |
| 堆損壞 | PageHeap / AddressSanitizer | `gflags /p /enable myapp.exe` (Windows) / `-fsanitize=address` (GCC/Clang) |
| 非確定性 Bug | rr Record & Replay | `rr record ./app` → `rr replay` 完美複現、反向執行 |
| 死鎖/競態 | ThreadSanitizer / Helgrind | `-fsanitize=thread` / `valgrind --tool=helgrind` |
| 效能熱點 | perf / VTune / 火焰圖 | `perf record -g ./app` → `perf script | flamegraph.pl >.svg` |
| Core Dump 分析 | GDB / WinDbg / LLDB | `gdb ./app core` → `bt` `info locals` `frame N` |
| 格式化輸出 | fmt / spdlog / {fmt} | `spdlog::info("User {} logged in from {}", name, ip);` 型別安全、高效能、非同步 |