#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include "dump.h" #include extern QString gAppNameStr; static uintptr_t g_base_address = 0; static int find_base_address(struct dl_phdr_info *info, size_t size, void *data) { (void)size; (void)data; if (info->dlpi_name == nullptr || info->dlpi_name[0] == '\0') { g_base_address = info->dlpi_addr; return 1; } return 0; } static uintptr_t get_base_address() { if (g_base_address == 0) { dl_iterate_phdr(find_base_address, nullptr); } return g_base_address; } void createStackTraceFile(const char *fileName, const char *appName) { std::ofstream file(fileName); if (!file.is_open()) { std::cerr << "Error opening file: " << fileName << std::endl; return; } void *array[50]; size_t size; char **strings; size = backtrace(array, 50); if (size == 0) { std::cerr << "No stack frames obtained" << std::endl; return; } uintptr_t base_addr = get_base_address(); strings = backtrace_symbols(array, size); file << "Stack trace info:\n"; file << "Base address: 0x" << std::hex << base_addr << std::dec << "\n\n"; for (size_t i = 0; i < size; ++i) { file << strings[i] << std::endl; uintptr_t addr = reinterpret_cast(array[i]); uintptr_t offset = addr - base_addr; char cmd[512]; snprintf(cmd, sizeof(cmd), "addr2line -e %s 0x%lx", appName, offset); FILE *fp = popen(cmd, "r"); if (fp) { char line[256]; while (fgets(line, sizeof(line), fp)) { file << " " << line; } pclose(fp); } else { std::cerr << "Failed to run addr2line command" << std::endl; } file << std::endl; } free(strings); file.close(); } static void signalHandler(int signum) { QString dumpFileName = QString("/home/plg/loginfo/dumpfile_%1.txt").arg(QDateTime::currentDateTime().toString("yyyy_MM_dd_hh_mm_ss")); QString appName = gAppNameStr; createStackTraceFile(dumpFileName.toUtf8().data(), appName.toUtf8().data()); exit(signum); } void installSignalHandlers() { signal(SIGSEGV, signalHandler); signal(SIGABRT, signalHandler); signal(SIGILL, signalHandler); signal(SIGFPE, signalHandler); }