2026-06-30_18_19 缓存

This commit is contained in:
2026-07-01 08:16:05 +08:00
parent 14d97b9bcb
commit ea3c3fb234
8 changed files with 248 additions and 16 deletions
+108
View File
@@ -1,3 +1,8 @@
#define _GNU_SOURCE // 必须放在所有头文件之前
#include <link.h> // dl_iterate_phdr 的声明
#include <dlfcn.h> // dladdr 等
#include <execinfo.h> // backtrace
#include <QApplication>
#include <QVBoxLayout>
#include <InputMethod.h>
@@ -20,6 +25,103 @@
#include "mainwidget.h"
#include "InkJetPrinter.h"
#include "Log/filelogger.h"
#include <iostream>
#include <fstream>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <cxxabi.h>
#include <cstdlib>
#include <cstdio>
#include <execinfo.h>
QString gAppNameStr = "";//这是个全局变量,用于后续获取当前运行程序的绝对路径
// 全局变量保存基址
static uintptr_t g_base_address = 0;
// 回调函数:找到当前可执行文件的基址
static int find_base_address(struct dl_phdr_info *info, size_t size, void *data) {
// 检查是否是主程序(第一个加载的通常是主程序)
if (info->dlpi_name == nullptr || info->dlpi_name[0] == '\0') {
// 获取第一个段的加载地址(通常是基址)
g_base_address = info->dlpi_addr;
return 1; // 停止遍历
}
return 0; // 继续遍历
}
// 获取程序基址的函数
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[100];
size_t size;
char **strings;
size = backtrace(array, 100);
if (size == 0) {
std::cerr << "No stack frames obtained" << std::endl;
return;
}
// 获取程序基址(PIE需要)
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<uintptr_t>(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();
}
void signalHandler(int signum)
{
// 直接指定固定的路径
QString dumpFileName = "/home/plg/doc/dumpfile.txt";
QString appName = gAppNameStr;
createStackTraceFile(dumpFileName.toUtf8().data(), appName.toUtf8().data());
exit(signum);
}
//#define SYS_CN
/*
@@ -72,6 +174,12 @@ int main(int argc, char *argv[])
QApplication a(argc, argv);
gAppNameStr = QString::fromUtf8(argv[0]);
signal(SIGSEGV, signalHandler);
signal(SIGABRT, signalHandler);
signal(SIGILL, signalHandler);
signal(SIGFPE, signalHandler);
// 配置日志
QString configFileName = ":/conf/config.ini";
QSettings* logSettings = new QSettings(configFileName, QSettings::IniFormat, &a);