AutoDmp.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include "AutoDmp.h"
  2. #include <unistd.h>
  3. #include <sys/syscall.h>
  4. #include <cstdlib>
  5. #include <ctime>
  6. #include <string>
  7. #include <sstream>
  8. #include <fstream>
  9. #include <iomanip>
  10. const int AutoDmp::handled_signals[] = {
  11. SIGSEGV, SIGABRT, SIGFPE, SIGILL, SIGBUS, SIGSYS
  12. };
  13. // 获取当前时间字符串
  14. std::string getCurrentTimeString() {
  15. time_t now = time(nullptr);
  16. struct tm tstruct;
  17. char buf[80];
  18. tstruct = *localtime(&now);
  19. strftime(buf, sizeof(buf), "%Y%m%d-%H%M%S", &tstruct);
  20. return std::string(buf);
  21. }
  22. // 生成核心转储文件名
  23. std::string generateCoreFileName() {
  24. std::ostringstream oss;
  25. oss << "core_" << getCurrentTimeString()
  26. << "_PID" << getpid()
  27. << "_TID" << syscall(SYS_gettid);
  28. return oss.str();
  29. }
  30. // 信号处理函数
  31. void AutoDmp::signalHandler(int sig, siginfo_t* info, void* context) {
  32. // 获取信号名称
  33. const char* sig_name = "UNKNOWN";
  34. switch (sig) {
  35. case SIGSEGV: sig_name = "SIGSEGV"; break;
  36. case SIGABRT: sig_name = "SIGABRT"; break;
  37. case SIGFPE: sig_name = "SIGFPE"; break;
  38. case SIGILL: sig_name = "SIGILL"; break;
  39. case SIGBUS: sig_name = "SIGBUS"; break;
  40. case SIGSYS: sig_name = "SIGSYS"; break;
  41. }
  42. // 生成错误信息
  43. std::ostringstream errorInfo;
  44. errorInfo << "Crash time: " << getCurrentTimeString() << "\n"
  45. << "Signal: " << sig_name << " (" << sig << ")\n"
  46. << "Fault address: " << info->si_addr << "\n"
  47. << "Process ID: " << getpid() << "\n"
  48. << "Thread ID: " << syscall(SYS_gettid) << "\n"
  49. << "Build: " << __DATE__ << " " << __TIME__ << "\n";
  50. // 写入错误日志
  51. std::string logName = "crash_" + getCurrentTimeString() + ".log";
  52. std::ofstream logFile(logName);
  53. if (logFile) {
  54. logFile << errorInfo.str();
  55. logFile.flush();
  56. }
  57. // 生成核心转储
  58. std::string coreName = generateCoreFileName();
  59. std::string cmd = "gcore -o " + coreName + " " + std::to_string(getpid());
  60. system(cmd.c_str());
  61. // 恢复默认处理并重新触发信号
  62. struct sigaction sa;
  63. sa.sa_handler = SIG_DFL;
  64. sigemptyset(&sa.sa_mask);
  65. sa.sa_flags = 0;
  66. sigaction(sig, &sa, NULL);
  67. kill(getpid(), sig);
  68. }
  69. void AutoDmp::installSignalHandlers() {
  70. struct sigaction sa;
  71. sa.sa_sigaction = signalHandler;
  72. sigemptyset(&sa.sa_mask);
  73. sa.sa_flags = SA_SIGINFO | SA_NODEFER;
  74. for (int i = 0; i < 6; i++) {
  75. sigaction(handled_signals[i], &sa, &old_actions[i]);
  76. }
  77. }
  78. void AutoDmp::restoreSignalHandlers() {
  79. for (int i = 0; i < 6; i++) {
  80. sigaction(handled_signals[i], &old_actions[i], NULL);
  81. }
  82. }
  83. AutoDmp::AutoDmp() {
  84. installSignalHandlers();
  85. }
  86. AutoDmp::~AutoDmp() {
  87. restoreSignalHandlers();
  88. }