static const int BACKSTRACE_TIME_SIZE = 128;
static const mode_t LOG_FILE_MODE = 0600;
static const char *COMPILE_DATE = "compile date: " __DATE__ ", " __TIME__;
static void SigBacktraceHandle(int sig)
{
std::string coreLogPath = "./backtrace.log";
// core的栈信息,写入到该文件,backtrace_symbol_fd 是异步信号处理安全的
int btfd = open(coreLogPath.c_str(), O_RDWR | O_APPEND | O_CLOEXEC | O_CREAT, LOG_FILE_MODE);
if (btfd != -1) {
char buff[BACKSTRACE_TIME_SIZE] = {0};
time_t currTime = time(nullptr);
ssize_t res;
int spRes;
// 避免调用可能as_not_safe的接口,时间直接打印出来,使用linux命令转换成年月日,例 date -d @1608348620
if (sig == SIGXCPU) {
spRes = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1, "\n# DEADLOOP time: %ld, sig: %d, tid: %ld\n", currTime, sig, GETTID());
} else {
spRes = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1, "\n# CORE time: %ld, sig: %d, tid: %ld\n", currTime, sig, GETTID());
}
if (spRes != -1) {
res = write(btfd, buff, strlen(buff));
}
spRes = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1, "# %s\n", "01");
if (spRes != -1) {
res = write(btfd, buff, strlen(buff));
}
spRes = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1, "# %s\n\n", COMPILE_DATE);
if (spRes != -1) {
res = write(btfd, buff, strlen(buff));
}
res = res;
void *array[32]; // 支持最大栈长度 32
int stackNum = backtrace(array, 32); // 支持最大栈长度 32
backtrace_symbols_fd(array, stackNum, btfd);
if (sig != SIGXCPU) {
close(btfd);
btfd = -1;
}
}
if (sig != SIGXCPU) {
signal(sig, SIG_DFL);
raise(sig);
}
}
static void ExitHandle(int status, void *)
{
std::string coreLogPath = "./backtrace.log";
// core的栈信息,写入到该文件,backtrace_symbol_fd 是异步信号处理安全的
int btfd = open(coreLogPath.c_str(), O_RDWR | O_APPEND | O_CLOEXEC | O_CREAT, LPMS_LOG_FILE_MODE);
if (btfd < 0) {
return;
}
char buff[BACKSTRACE_TIME_SIZE] = {0};
time_t currTime = time(nullptr);
ssize_t res;
// 避免调用可能as_not_safe的接口,时间直接打印出来,使用linux命令转换成年月日,例 date -d @1608348620
int spRes = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1, "\n# EXIT time: %ld, status: %d\n", currTime, status);
if (spRes != -1) {
res = write(btfd, buff, strlen(buff));
}
spRes = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1, "# %s\n", "01");
if (spRes != -1) {
res = write(btfd, buff, strlen(buff));
}
spRes = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1, "# %s\n\n", COMPILE_DATE);
if (spRes != -1) {
res = write(btfd, buff, strlen(buff));
}
res = res;
void *array[32]; // 支持最大栈长度 32
int stackNum = backtrace(array, 32); // 支持最大栈长度 32
backtrace_symbols_fd(array, stackNum, btfd);
close(btfd);
btfd = -1;
}
static void CatchSignals()
{
// backtrace函数非异步信号安全,通用做法启动先调用下backtrace,防止首次调用动态加载库导致信号处理中malloc
void *dummy = nullptr;
backtrace(&dummy, 1);
// ignore
(void)signal(SIGPIPE, SIG_IGN);
// core
(void)signal(SIGABRT, SigBacktraceHandle);
(void)signal(SIGSEGV, SigBacktraceHandle);
(void)signal(SIGILL, SigBacktraceHandle);
(void)signal(SIGFPE, SigBacktraceHandle);
(void)signal(SIGBUS, SigBacktraceHandle);
#ifdef DEBUG_DEADLOOP
(void)signal(SIGXCPU, SigBacktraceHandle);
#endif
(void)on_exit(ExitHandle, nullptr);
}