Crash 崩溃处理
C++ 后端服务器框架Crash 崩溃处理
CHAPTER 05

Crash 崩溃处理

2 分钟阅读 · 498 字

对应文件:

  • 接口:include/Crash.h
  • 实现:src/Crash.cpp

1. 模块定位

CrashHandler 提供进程级异常与信号兜底,目标是:

  • 捕获致命信号与未处理异常
  • 统一执行清理逻辑
  • 输出崩溃信息与日志
  • 安全退出进程

2. 核心能力

2.1 初始化注册:init(cleanupFunc)

注册内容:

  • std::set_terminate(terminateHandler):未捕获 C++ 异常
  • 通用信号:SIGINT/SIGTERM/SIGSEGV/SIGABRT/SIGILL/SIGFPE
  • Linux 额外:SIGBUS/SIGQUIT
  • Windows 额外:
    • SetUnhandledExceptionFilter(sehExceptionHandler)(SEH)
    • SetConsoleCtrlHandler(consoleCtrlHandler, TRUE)(控制台关闭事件)

2.2 统一退出入口:gracefulExit(exitCode, reason)

关键流程:

  1. isExiting_.exchange(true) 防止重复重入
  2. 互斥锁保护退出阶段
  3. 打印 reason / exitCode
  4. printCrashInfo(...) 输出诊断信息
  5. 调用业务清理回调 cleanupCallback_
  6. 进程退出:
    • Windows:ExitProcess
    • Linux:_exit

2.3 诊断输出:printCrashInfo

  • 按编译器分支处理:
    • MSVC
    • MinGW
    • Linux
  • 统一追加写 crash_log.txt
  • 记录时间、退出码、原因、编译器信息

3. 与 Server 的接入方式

Server 构造时调用:

  • CrashHandler::instance().init([this]() { this->cleanup(); });

意味着崩溃退出时会先走服务资源清理(socket、调度器等)。

4. 并发与可重入控制

  • std::atomic<bool> isExiting_:确保只执行一次退出流程
  • std::mutex exitMutex_:序列化退出日志与清理动作

5. 宏能力:SAFE_ASSERT

SAFE_ASSERT(expr) 失败时不会直接 abort,而是进入 gracefulExit,便于统一清理和记录。

6. 设计优点

  • 跨平台覆盖较全(信号 + C++ terminate + Windows SEH)
  • 退出路径统一,业务清理可注入
  • 输出信息落盘,便于排查

7. 风险与建议

  • 在信号处理上下文中执行复杂逻辑(I/O、锁、分配)存在异步信号安全风险
    • 可改为“最小化信号处理 + 置标志 + 专用监控线程收尾”
  • printCrashInfo 目前平台差异实现不完全一致
    • 建议统一抽象栈回溯接口
  • _exit 会跳过静态析构与部分清理
    • 这是故障场景常见取舍,面试时可说明“优先保证可控退出”
全部章节