// PerfTraceMark.h —— 极轻量的"某函数被调用过"打点,用于在没有调试器时定位调用路径 // // 用法:在候选函数入口写 PerfTraceMark("函数名"), // 每次进程内该 tag 只记录第一次,追加到 %TEMP%\aec_writeback_trace.txt。 // 只在 Debug(NDEBUG 未定义)且环境变量 AEC_WRITEBACK_TRACE=1 时生效,发布版本零开销。 // // 为什么不用 SectionPerf:AecRxBase.arx 不链接 CoreLibrary(静态库只被 CoreCommand 链接), // 所以 AecRxBase 的文件里拿不到 SectionPerf 的符号。本头文件是 inline 的,哪个模块都能用。 #ifndef PERF_TRACE_MARK_H #define PERF_TRACE_MARK_H #include #include #include #include #include inline void PerfTraceMark(const char* pszTag) { #ifndef NDEBUG static bool s_bInit = false; static bool s_bOn = false; static std::set s_seen; if (!s_bInit) { s_bInit = true; const char* psz = ::getenv("AEC_WRITEBACK_TRACE"); s_bOn = (psz != NULL && psz[0] != '0'); } if (!s_bOn || pszTag == NULL) return; const std::string sTag(pszTag); if (s_seen.find(sTag) != s_seen.end()) return; s_seen.insert(sTag); char szTmp[MAX_PATH + 1]; ::memset(szTmp, 0, sizeof(szTmp)); if (::GetTempPathA(MAX_PATH, szTmp) == 0) return; std::string sPath(szTmp); sPath += "aec_writeback_trace.txt"; FILE* fp = NULL; if (fopen_s(&fp, sPath.c_str(), "ab") == 0 && fp != NULL) { fprintf(fp, "[mark] %s\n", pszTag); fclose(fp); } #else (void)pszTag; #endif } #endif // PERF_TRACE_MARK_H