# AutoDmp - Linux专用崩溃检测与转储工具 AutoDmp 是一个针对 Linux 系统优化的崩溃检测和转储生成工具,专门处理 Linux 信号和 core dump。 ## ✨ 主要特性 ### 🛡️ Linux专用安全机制 - **异步安全**: 信号处理器只使用异步安全函数 - **线程安全**: 使用原子操作防止竞争条件 - **防重入保护**: 避免信号处理器递归调用 - **双重输出**: 异步安全的即时输出 + 详细的崩溃日志 ### 🔧 Linux系统集成 - **Core Dump**: 自动设置 ulimit 并生成标准 core dump - **详细调用栈**: 使用 `backtrace()` 获取完整调用链 - **信号详解**: 详细解析各种 Linux 信号和错误代码 - **进程信息**: PID、TID、进程名、构建信息等 ### 📊 多种输出模式 - **即时输出**: 异步安全的 stderr 输出(崩溃时立即可见) - **详细日志**: 完整的崩溃报告文件 - **Core Dump**: 标准的 Linux core dump 文件 - **自动清理**: 限制保留文件数量 ## 🚀 快速开始 ### 最简单的使用方式 ```cpp #include \"AutoDmp.h\" int main() { // 一行代码启用Linux崩溃检测 ENABLE_CRASH_HANDLER(); // 你的程序代码... return 0; } ``` ### Linux专用配置 ```cpp #include \"AutoDmp.h\" int main() { // Linux专用配置 CrashConfig config; config.enableCoreDump = true; // 启用core dump config.enableConsoleOutput = true; // 启用控制台输出 config.enableLogFile = true; // 启用详细日志 config.enableBacktrace = true; // 启用调用栈 config.crashDirectory = \"./crashes\"; // 崩溃文件目录 config.maxCrashFiles = 10; // 最大保留文件数 config.maxBacktraceDepth = 128; // 调用栈最大深度 config.enableDetailedInfo = true; // 启用详细信息 config.asyncSafeOnly = false; // 允许非异步安全操作 // 使用配置启用 ENABLE_CRASH_HANDLER_WITH_CONFIG(config); // 你的程序代码... return 0; } ``` ### 面向对象方式 ```cpp #include \"AutoDmp.h\" int main() { // 创建Linux崩溃处理器 CrashConfig config; config.crashDirectory = \"./my_crashes\"; config.enableCoreDump = true; AutoDmp crashHandler(config); if (crashHandler.isInitialized()) { std::cout << \"Linux崩溃检测已启用\" << std::endl; // 查看支持的信号 const int* signals = AutoDmp::getSupportedSignals(); size_t count = AutoDmp::getSupportedSignalCount(); std::cout << \"监控 \" << count << \" 种Linux信号\" << std::endl; } // 你的程序代码... return 0; // 析构时自动清理 } ``` ## 📁 输出文件 ### Core Dump 文件 - **位置**: 当前目录或系统配置的位置 - **名称**: `core` 或 `core.PID` - **用途**: 使用 GDB 进行详细调试 ### 崩溃日志文件 - **位置**: `./crashes/crash_YYYYMMDD-HHMMSS.xxx.log` - **格式**: 详细的文本报告 ### 日志内容示例 ``` ==================== LINUX CRASH REPORT ==================== Timestamp: 20231215-143022.456 Process: MyApp (PID: 1234) Thread ID: 5678 Build Info: Dec 15 2023 14:29:30 Signal: SIGSEGV (11) Signal Description: SIGSEGV - Segmentation fault (address not mapped) Fault Address: 0x0 Detailed Backtrace: #00: ./MyApp(_Z18testSegFaultv+0x12)[0x401234] #01: ./MyApp(main+0x45)[0x401156] #02: /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x7f8b2c0230b3] #03: ./MyApp(_start+0x2e)[0x40105e] ============================================================ ``` ## 🔧 Linux配置选项 | 选项 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `enableCoreDump` | bool | true | 是否生成 core dump | | `enableConsoleOutput` | bool | true | 是否异步安全输出到 stderr | | `enableLogFile` | bool | true | 是否生成详细日志文件 | | `enableBacktrace` | bool | true | 是否生成调用栈 | | `crashDirectory` | string | \"./crashes\" | 崩溃文件目录 | | `maxCrashFiles` | size_t | 10 | 最大保留文件数 | | `maxBacktraceDepth` | size_t | 128 | 调用栈最大深度 | | `enableSymbols` | bool | true | 是否启用符号解析 | | `enableDetailedInfo` | bool | true | 是否启用详细信息输出 | | `asyncSafeOnly` | bool | true | 是否只使用异步安全函数 | ## 🧪 测试 ### 编译 ```bash # GCC编译 g++ -std=c++11 -g -O0 -o test_crash test_crash.cpp AutoDmp.cpp -ldl -lpthread # 确保能生成core dump ulimit -c unlimited # 运行测试 ./test_crash ``` ### 支持的测试场景 1. **段错误** (SIGSEGV) - 空指针解引用 2. **浮点异常** (SIGFPE) - 除零错误 3. **栈溢出** (SIGSEGV) - 无限递归 4. **异常终止** (SIGABRT) - abort() 调用 5. **非法指令** (SIGILL) - 未定义指令 6. **总线错误** (SIGBUS) - 内存对齐错误 7. **数组越界** (SIGSEGV) - 大量越界访问 8. **多线程崩溃** (SIGSEGV) - 子线程崩溃 9. **管道错误** (SIGPIPE) - 向关闭的管道写入 10. **用户信号** (SIGUSR1) - 安全测试 ## 📋 支持的Linux信号 | 信号 | 数值 | 描述 | 常见原因 | |------|------|------|----------| | `SIGSEGV` | 11 | 段错误 | 空指针、越界访问 | | `SIGABRT` | 6 | 异常终止 | abort()、断言失败 | | `SIGFPE` | 8 | 浮点异常 | 除零、溢出 | | `SIGILL` | 4 | 非法指令 | 损坏的代码、架构不匹配 | | `SIGBUS` | 7 | 总线错误 | 内存对齐、硬件错误 | | `SIGSYS` | 31 | 系统调用错误 | 无效系统调用 | | `SIGPIPE` | 13 | 管道错误 | 向关闭的管道写入 | | `SIGQUIT` | 3 | 退出信号 | Ctrl+\\ | ## 🔍 使用Core Dump调试 ### 基本调试流程 ```bash # 1. 编译时包含调试信息 g++ -g -O0 -o myapp main.cpp AutoDmp.cpp -ldl # 2. 运行程序(崩溃后会生成core文件) ./myapp # 3. 使用GDB分析core dump gdb ./myapp core # 4. GDB常用命令 (gdb) bt # 查看调用栈 (gdb) bt full # 查看详细调用栈(含变量) (gdb) info locals # 查看局部变量 (gdb) print var # 打印变量值 (gdb) list # 查看源代码 (gdb) frame 0 # 切换到栈帧0 (gdb) info threads # 查看所有线程 (gdb) thread 1 # 切换到线程1 ``` ### 高级调试技巧 ```bash # 查看内存映射 (gdb) info proc mappings # 查看寄存器状态 (gdb) info registers # 查看汇编代码 (gdb) disassemble # 查看共享库 (gdb) info sharedlibrary # 设置断点重现问题 (gdb) break main (gdb) run ``` ## ⚠️ Linux特有注意事项 ### 1. Core Dump 设置 ```bash # 检查core dump设置 ulimit -c # 启用core dump(无限制) ulimit -c unlimited # 设置core文件命名规则 echo 'core.%p.%t' | sudo tee /proc/sys/kernel/core_pattern ``` ### 2. 权限要求 - 进程需要有写入崩溃目录的权限 - Core dump 需要有足够的磁盘空间 - 某些安全模块(如SELinux)可能限制core dump ### 3. 符号信息 ```bash # 安装调试符号(Ubuntu/Debian) sudo apt-get install libc6-dbg # 设置符号路径 export DEBUGINFOD_URLS=\"https://debuginfod.ubuntu.com\" ``` ### 4. 多线程注意事项 - 崩溃处理在任意线程中都能正确工作 - 调用栈会显示崩溃时的具体线程 - 可以使用 `info threads` 查看所有线程状态 ### 5. 性能考虑 - 异步安全输出几乎无性能损失 - 详细日志记录会有轻微开销 - Core dump 大小取决于进程内存使用 ### 编译要求 - Linux 系统(已测试:Ubuntu 18.04+, CentOS 7+) - GCC 4.8+ 或 Clang 3.8+ - C++11 支持 - glibc 2.17+ ### 依赖库 - `libdl` - 动态链接 - `libpthread` - 多线程支持 - `libc` - 标准C库(backtrace支持) 如有问题或建议,请联系项目维护团队。 ## 📄 许可证 本项目采用内部使用许可,仅供内部开发使用。