You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

40 lines
2.0 KiB
C

// crash_handler.h - 崩溃现场捕获与死因日志
//
// 解决问题:程序在客户机上"双击后无声消失",控制台一闪而过、运行日志(run.log)
// 因缓冲未落盘而什么都不剩,无法定位原因。
//
// 本模块在 main() 最开头安装以下钩子,任何一条被触发都会把死因写入
// <log_dir>/YYYYMMDD/crash.log (默认 data/YYYYMMDD/crash.log)
// 写失败时自动回退到 exe 同目录 crash.log,再回退到系统临时目录。
//
// 捕获范围(Windows):
// - SEH 异常:访问违规 0xC0000005、栈溢出 0xC00000FD、除零 0xC0000094、
// 非法指令 0xC000001D、DLL 未找到/初始化失败等(SetUnhandledExceptionFilter)
// - abort():未处理异常 / 断言失败 / std::thread 析构时仍 joinable(SIGABRT)
// - std::terminate:未捕获的 C++ 异常(std::set_terminate)
// - new 失败:std::bad_alloc(std::set_new_handler)
// 记录内容:异常码+含义、出错地址(模块+偏移)、符号名与源码行号(有 dbghelp 时)、
// 完整调用栈、崩溃前最后一个"里程碑"、并生成 .dmp 供事后用 VS/WinDbg 分析。
//
// 使用:
// install_crash_handlers(); // main() 第一行
// CRASH_MILESTONE("配置加载完成"); // 关键节点打点,崩溃时一并输出
#ifndef CRASH_HANDLER_H
#define CRASH_HANDLER_H
// 安装全部崩溃钩子;可重复调用(幂等)。log_dir 为崩溃日志根目录(相对当前工作目录)。
void install_crash_handlers(const char* log_dir = "data");
// 记录运行里程碑:同时打印到控制台(进 run.log)并记住最后一条,
// 崩溃时一并写入 crash.log,用于判断"程序死在哪一步"。printf 风格。
void crash_milestone(const char* fmt, ...);
// 主动写一条严重错误(不终止进程),printf 风格。
void crash_log(const char* fmt, ...);
// 便捷宏
#define CRASH_MILESTONE(...) crash_milestone(__VA_ARGS__)
#define CRASH_LOG(...) crash_log(__VA_ARGS__)
#endif // CRASH_HANDLER_H