linux 生成core文件

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);
}

你可能感兴趣的:(LINUX,linux,运维,服务器)