Added a crash reporter

This commit is contained in:
vaxerski 2023-02-19 13:45:56 +00:00
parent 6548439f6c
commit 38c25bb50d
6 changed files with 121 additions and 4 deletions

View file

@ -100,6 +100,9 @@ target_compile_definitions(Hyprland PRIVATE "-DGIT_BRANCH=\"${GIT_BRANCH}\"")
target_compile_definitions(Hyprland PRIVATE "-DGIT_COMMIT_MESSAGE=\"${GIT_COMMIT_MESSAGE}\"") target_compile_definitions(Hyprland PRIVATE "-DGIT_COMMIT_MESSAGE=\"${GIT_COMMIT_MESSAGE}\"")
target_compile_definitions(Hyprland PRIVATE "-DGIT_DIRTY=\"${GIT_DIRTY}\"") target_compile_definitions(Hyprland PRIVATE "-DGIT_DIRTY=\"${GIT_DIRTY}\"")
ADD_LINK_OPTIONS( -rdynamic )
SET(CMAKE_ENABLE_EXPORTS TRUE)
target_link_libraries(Hyprland rt) target_link_libraries(Hyprland rt)
set(CPACK_PROJECT_NAME ${PROJECT_NAME}) set(CPACK_PROJECT_NAME ${PROJECT_NAME})

View file

@ -2,6 +2,7 @@
#include "helpers/Splashes.hpp" #include "helpers/Splashes.hpp"
#include <random> #include <random>
#include "debug/HyprCtl.hpp" #include "debug/HyprCtl.hpp"
#include "debug/CrashReporter.hpp"
#ifdef USES_SYSTEMD #ifdef USES_SYSTEMD
#include <systemd/sd-daemon.h> // for sd_notify #include <systemd/sd-daemon.h> // for sd_notify
#endif #endif
@ -16,6 +17,11 @@ int handleCritSignal(int signo, void* data) {
return 0; // everything went fine return 0; // everything went fine
} }
void handleSegv(int sig) {
CrashReporter::createAndSaveCrash();
exit(SIGSEGV);
}
CCompositor::CCompositor() { CCompositor::CCompositor() {
wlr_log_init(WLR_INFO, NULL); wlr_log_init(WLR_INFO, NULL);
@ -61,6 +67,7 @@ CCompositor::CCompositor() {
// register crit signal handler // register crit signal handler
wl_event_loop_add_signal(m_sWLEventLoop, SIGTERM, handleCritSignal, nullptr); wl_event_loop_add_signal(m_sWLEventLoop, SIGTERM, handleCritSignal, nullptr);
signal(SIGSEGV, handleSegv);
//wl_event_loop_add_signal(m_sWLEventLoop, SIGINT, handleCritSignal, nullptr); //wl_event_loop_add_signal(m_sWLEventLoop, SIGINT, handleCritSignal, nullptr);
m_sWLRBackend = wlr_backend_autocreate(m_sWLDisplay, &m_sWLRSession); m_sWLRBackend = wlr_backend_autocreate(m_sWLDisplay, &m_sWLRSession);

View file

@ -0,0 +1,93 @@
#include "CrashReporter.hpp"
#include <random>
#include <sys/utsname.h>
#include <execinfo.h>
#include <fstream>
std::string getRandomMessage() {
const std::vector<std::string> MESSAGES = {"Sorry, didn't mean to...",
"This was an accident, I swear!",
"Calm down, it was a misinput! MISINPUT!",
"Oops",
"Vaxry is going to be upset.",
"Who tried dividing by zero?!",
"Maybe you should try dusting your PC in the meantime?",
"I tried so hard, and got so far...",
"I don't feel so good...",
"*thud*",
"Well this is awkward.",
"\"stable\"",
"I hope you didn't have any unsaved progress."};
std::random_device dev;
std::mt19937 engine(dev());
std::uniform_int_distribution<> distribution(0, MESSAGES.size() - 1);
return MESSAGES[distribution(engine)];
}
void CrashReporter::createAndSaveCrash() {
// get the backtrace
const int PID = getpid();
std::string finalCrashReport = "";
finalCrashReport += "--------------------------------------------\n Hyprland Crash Log\n--------------------------------------------\n";
finalCrashReport += getRandomMessage() + "\n\n";
finalCrashReport += "Hyprland received signal 11 (SIGSEGV): Segmentation Fault\n\n";
finalCrashReport += "System info:\n";
struct utsname unameInfo;
uname(&unameInfo);
finalCrashReport +=
getFormat("\tSystem name: %s\n\tNode name: %s\n\tRelease: %s\n\tVersion: %s\n\n", unameInfo.sysname, unameInfo.nodename, unameInfo.release, unameInfo.version);
const std::string GPUINFO = execAndGet("lspci -vnn | grep VGA");
finalCrashReport += "GPU:\n\t" + GPUINFO;
finalCrashReport += getFormat("\n\nos-release:\n\t%s\n\n\n", replaceInString(execAndGet("cat /etc/os-release"), "\n", "\n\t").c_str());
finalCrashReport += "Backtrace:\n";
void* bt[1024];
size_t btSize;
char** btSymbols;
btSize = backtrace(bt, 1024);
btSymbols = backtrace_symbols(bt, btSize);
for (size_t i = 0; i < btSize; ++i) {
finalCrashReport += getFormat("\t#%i | %s\n", i, btSymbols[i]);
std::string btSymbol = btSymbols[i];
size_t hlPos = 0;
while (btSymbol.find("Hyprland", hlPos + 1) != std::string::npos) {
hlPos = btSymbol.find("Hyprland", hlPos + 1);
}
if (hlPos != 0) {
const auto CMD = getFormat("addr2line -e %s -f 0x%lx", btSymbol.substr(0, hlPos + 8).c_str(), (uint64_t)bt[i]);
const auto ADDR2LINE = replaceInString(execAndGet(CMD.c_str()), "\n", "\n\t\t");
finalCrashReport += "\t\t" + ADDR2LINE.substr(0, ADDR2LINE.length() - 2);
}
}
free(btSymbols);
const auto HOME = getenv("HOME");
if (!HOME)
return;
std::ofstream ofs(std::string(HOME) + "/.hyprlandDump" + std::to_string(PID), std::ios::trunc);
ofs << finalCrashReport;
ofs.close();
}

View file

@ -0,0 +1,7 @@
#pragma once
#include "../defines.hpp"
namespace CrashReporter {
void createAndSaveCrash();
};

View file

@ -549,4 +549,13 @@ double normalizeAngleRad(double ang) {
} }
return ang; return ang;
}
std::string replaceInString(std::string subject, const std::string& search, const std::string& replace) {
size_t pos = 0;
while ((pos = subject.find(search, pos)) != std::string::npos) {
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
return subject;
} }

View file

@ -16,9 +16,7 @@ void logSystemInfo();
std::string execAndGet(const char*); std::string execAndGet(const char*);
int64_t getPPIDof(int64_t pid); int64_t getPPIDof(int64_t pid);
int64_t configStringToInt(const std::string&); int64_t configStringToInt(const std::string&);
float getPlusMinusKeywordResult(std::string in, float relative); float getPlusMinusKeywordResult(std::string in, float relative);
void matrixProjection(float mat[9], int w, int h, wl_output_transform tr); void matrixProjection(float mat[9], int w, int h, wl_output_transform tr);
double normalizeAngleRad(double ang);
double normalizeAngleRad(double ang); std::string replaceInString(std::string subject, const std::string& search, const std::string& replace);