106 lines
2.5 KiB
C++
106 lines
2.5 KiB
C++
#define _GNU_SOURCE
|
|
#include <link.h>
|
|
#include <dlfcn.h>
|
|
#include <execinfo.h>
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <signal.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <cxxabi.h>
|
|
#include <cstdlib>
|
|
#include <cstdio>
|
|
|
|
#include <QString>
|
|
#include "dump.h"
|
|
#include <QDateTime>
|
|
|
|
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<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();
|
|
}
|
|
|
|
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);
|
|
} |