2026-06-30_18_19 缓存
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user