c++ 程序打印 core dump 信息

发布时间 2023-11-02 17:47:42作者: 卑以自牧lq

linux 环境下 c++ 程序打印 core dump 信息

linux 信号机制

c++ 打印堆栈信息

#include <signal.h>
#include <execinfo.h>
#include <dlfcn.h>
#include <cxxabi.h>
#include <QFile>
#include <QTextStream>

// 捕获信号,对于这些信号都执行 coreDumpHandle
signal(SIGQUIT, coreDumpHandle);
signal(SIGILL, coreDumpHandle);
signal(SIGABRT, coreDumpHandle);
signal(SIGSEGV, coreDumpHandle);
signal(SIGTRAP, coreDumpHandle);

void coreDumpHandle(int signum) {
    string path = "/xxx/xxx/coreDump.log";
    
    void* callStack[128];
    int frames = backstrace(callStack, sizeof(callStack) / sizeof(callStack[0]));
    char** strs = backtrack_symbols(callStack, frames);

    if (strs == nullptr)
        exit(0);

    QFile out(path.c_str());
    if (!out.open(QIODevice::WrietOnly | QIODevece::Text | QIODevice::Truncate)) {
        exit(0);
    }

    QTextStream textStream(&out);
    textStream << "Get signal: " << strsignal(signum) << "\n";
    textStream << "Call stack:\n";

    unsigned count = 0;
    for (int i = 0; i < frames; ++i) {
        Dl_info info;
        if (dladdr(callStack[i], &info) && info.dli_sname) {
            int status;
            char* demangled = abi::__cxa_demangle(info.dli_sname, nullptr, nullptr, &status);
            if (status == 0) {
                QString str = QString("[%1] %2 : %3 0x%4\n").arg(count++)
                        .arg(info.dli_fname)
                        .arg(demangled)
                        .arg(reinterpret_cast<quintptr>(((void*)callStack[i])), 0, 16);
                textStream << str;
            } else {
                QString str = QString("[%1] %2 : %3 0x%4\n").arg(count++)
                        .arg(info.dli_fname)
                        .arg(info.dli_fname)
                        .arg(reinterpret_cast<quintptr>(((void*)callStack[i])), 0, 16);
                textStream << str;
            }
            free(demangled);
        }
        else {
            // printf("[%d] %s : ???\n", i, info.dli_fname);
        }
    }
    out.close();
    free(strs);
    exit(0);
}