123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- #include "AutoDmp.h"
- #include <unistd.h>
- #include <sys/syscall.h>
- #include <cstdlib>
- #include <ctime>
- #include <string>
- #include <sstream>
- #include <fstream>
- #include <iomanip>
- const int AutoDmp::handled_signals[] = {
- SIGSEGV, SIGABRT, SIGFPE, SIGILL, SIGBUS, SIGSYS
- };
- // 获取当前时间字符串
- std::string getCurrentTimeString() {
- time_t now = time(nullptr);
- struct tm tstruct;
- char buf[80];
- tstruct = *localtime(&now);
- strftime(buf, sizeof(buf), "%Y%m%d-%H%M%S", &tstruct);
- return std::string(buf);
- }
- // 生成核心转储文件名
- std::string generateCoreFileName() {
- std::ostringstream oss;
- oss << "core_" << getCurrentTimeString()
- << "_PID" << getpid()
- << "_TID" << syscall(SYS_gettid);
- return oss.str();
- }
- // 信号处理函数
- void AutoDmp::signalHandler(int sig, siginfo_t* info, void* context) {
- // 获取信号名称
- const char* sig_name = "UNKNOWN";
- switch (sig) {
- case SIGSEGV: sig_name = "SIGSEGV"; break;
- case SIGABRT: sig_name = "SIGABRT"; break;
- case SIGFPE: sig_name = "SIGFPE"; break;
- case SIGILL: sig_name = "SIGILL"; break;
- case SIGBUS: sig_name = "SIGBUS"; break;
- case SIGSYS: sig_name = "SIGSYS"; break;
- }
- // 生成错误信息
- std::ostringstream errorInfo;
- errorInfo << "Crash time: " << getCurrentTimeString() << "\n"
- << "Signal: " << sig_name << " (" << sig << ")\n"
- << "Fault address: " << info->si_addr << "\n"
- << "Process ID: " << getpid() << "\n"
- << "Thread ID: " << syscall(SYS_gettid) << "\n"
- << "Build: " << __DATE__ << " " << __TIME__ << "\n";
- // 写入错误日志
- std::string logName = "crash_" + getCurrentTimeString() + ".log";
- std::ofstream logFile(logName);
- if (logFile) {
- logFile << errorInfo.str();
- logFile.flush();
- }
- // 生成核心转储
- std::string coreName = generateCoreFileName();
- std::string cmd = "gcore -o " + coreName + " " + std::to_string(getpid());
- system(cmd.c_str());
- // 恢复默认处理并重新触发信号
- struct sigaction sa;
- sa.sa_handler = SIG_DFL;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sigaction(sig, &sa, NULL);
- kill(getpid(), sig);
- }
- void AutoDmp::installSignalHandlers() {
- struct sigaction sa;
- sa.sa_sigaction = signalHandler;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_SIGINFO | SA_NODEFER;
- for (int i = 0; i < 6; i++) {
- sigaction(handled_signals[i], &sa, &old_actions[i]);
- }
- }
- void AutoDmp::restoreSignalHandlers() {
- for (int i = 0; i < 6; i++) {
- sigaction(handled_signals[i], &old_actions[i], NULL);
- }
- }
- AutoDmp::AutoDmp() {
- installSignalHandlers();
- }
- AutoDmp::~AutoDmp() {
- restoreSignalHandlers();
- }
|